
स्व-होस्टेड नियंत्रण डेक और टेलस्केल के माध्यम से लिनक्स वर्कस्टेशन के लिए रिमोट डेस्कटॉप, जिसमें वेबआरटीसी स्ट्रीमिंग, स्थानीय LLM के साथ वॉइस कंट्रोल, सीन मैक्रोज़, वर्चुअल इनपुट, फ़ाइल ट्रांसफ़र और लाइव सिस्टम टेलीमेट्री शामिल हैं।
एक अतिरिक्त एंड्रॉइड फ़ोन (या ब्राउज़र वाला कोई भी उपकरण) को अपने लिनक्स वर्कस्टेशन के लिए एक स्व-होस्टेड कंट्रोल डेक और रिमोट डेस्कटॉप में बदलें — आपके निजी टेलस्केल नेटवर्क पर, बिना किसी तीसरे पक्ष के ऐप के।
इसकी शुरुआत "पुराने फ़ोन का क्या करूँ?" से हुई और यह एक हाइपरलैंड रिग के लिए एक नियंत्रण प्लेन बन गया: विंडो/वर्कस्पेस नियंत्रण, दृश्य मैक्रो, स्थानीय-एलएलएम सहायक के साथ एक पुश-टू-टॉक वॉइस रूटर, संदर्भ-जागरूक इन-ऐप नियंत्रण, दो-तरफ़ा ऑडियो + स्क्रीन स्ट्रीमिंग, एक टच रिमोट-डेस्कटॉप, एक वर्चुअल कीबोर्ड/माउस, फ़ाइल स्थानांतरण + फ़ोन→PC साझाकरण, और लाइव टेलीमेट्री — सभी एक इंस्टॉल किए गए PWA के रूप में एक फ़ॉस्फ़र-टर्मिनल लुक के साथ परोसा जाता है।
पोर्टेबिलिटी पर ध्यान दें। यह एक विशिष्ट सेटअप के लिए बनाया गया था: Arch-आधारित लिनक्स (Garuda) + Hyprland + PipeWire + NVIDIA + Tailscale, end-4 / illogical-impulse डॉटफ़ाइल्स के साथ। आर्किटेक्चर सामान्य है, लेकिन कई एकीकरण पर्यावरण-विशिष्ट हैं (मॉनिटर नाम, वर्कस्पेस बाइंडिंग, matugen थीम पथ,
cpupower/nvidia-smi)। इसे एक तैयार पैकेज के बजाय अनुकूलित करने के लिए कार्यशील संदर्भ मानें।
यूआई एक टैब्ड, डार्क, लैंडस्केप वेब ऐप है (आपके डेस्कटॉप से थीम-सिंक):
| टैब | यह क्या करता है |
|---|---|
| वर्कस्पेस | लाइव प्रति-मॉनिटर वर्कस्पेस ग्रिड (स्विच करने के लिए टैप करें), लाइव विंडो सूची (फ़ोकस करने के लिए टैप करें), प्रति-मॉनिटर DPMS टॉगल + ddcutil ब्राइटनेस |
| रिमोट | ऑन-स्क्रीन ट्रैकपैड (ड्रैग/टैप/दो उंगली) + मॉडिफ़ायर और कॉम्बो के साथ वर्चुअल कीबोर्ड, एक कर्नेल uinput डिवाइस के माध्यम से |
| मोड | एक-टैप दृश्य मैक्रो — पूरे ऐप लेआउट को मॉनिटरों पर लॉन्च/बंद/व्यवस्थित करें (जैसे "काम" / "खाली") |
| वॉइस | पुश-टू-टॉक वॉइस रूटर (faster-whisper, CPU): लीड-वर्ड लेन — macro (एक मोड/कमांड चलाएँ), type (डिक्टेट), input (वाक्यांश → की कॉर्ड) — निष्पादित करने से पहले पुष्टि के साथ, साथ ही "friday", एक केवल-पढ़ने के लिए स्थानीय-एलएलएम उत्तरदाता (Ollama + Qwen) जिसमें स्व-होस्टेड वेब खोज और लाइव सिस्टम-स्थिति जागरूकता है |
| ऑडियो | माइक/स्पीकर म्यूट, वॉल्यूम, आउटपुट और इनपुट डिवाइस पिकर, playerctl ट्रांसपोर्ट + कवर आर्ट (सक्रिय MPRIS प्लेयर को ट्रैक करता है) |
| स्ट्रीम | द्विदिश WebRTC ऑडियो (PC↔फ़ोन, फ़ोन-एक-माइक और फ़ोन-केवल आउटपुट के साथ) + स्क्रीन वीडियो, और स्ट्रीम की गई स्क्रीन पर नियंत्रण करने के लिए टैप करें = एक वास्तविक रिमोट डेस्कटॉप |
| सिस्टम | प्रदर्शन-मोड टॉगल, लाइव थीम स्विचिंग, Tailscale स्थिति, शीर्ष प्रक्रियाएँ (मारने के लिए टैप करें), लॉक, NetworkManager पुनरारंभ, सस्पेंड/रीबूट/पावरऑफ़ |
| फ़ाइलें | मॉनिटर का स्क्रीनशॉट लें → फ़ोन पर देखें/डाउनलोड करें; फ़ोन→PC पर एक फ़ाइल ड्रॉप करें |
| कॉन्फ़िग | फ़ोन से commands.json / modes.json (और संदर्भ/वॉइस) कॉन्फ़िग संपादित करें (JSON-मान्य) |
हमेशा ऊपर, टैब के ऊपर — एक संदर्भ पट्टी जो अभी जो हो रहा है उसे सामने लाती है: एक सक्रिय कॉल (म्यूट करें/उस पर जाएँ), मीडिया अब-चल रहा है + ट्रांसपोर्ट, और फ़ोकस किए गए ऐप (YouTube / Brave / Teams) के लिए इन-ऐप कीबोर्ड नियंत्रण, फ़ोकस चुराए बिना वितरित।
दो और, टैब से परे:
प्लस: ऑन-स्क्रीन नम्पैड PIN लॉगिन, स्क्रीन वेक-लॉक, फ़ुलस्क्रीन लैंडस्केप PWA, और लॉगिन पर ब्रूट-फोर्स लॉकआउट।
फ़ोन / लैपटॉप (ब्राउज़र PWA)
│ HTTPS + WSS (केवल Tailscale)
▼
tailscale serve ──► FastAPI वेब ऐप ── यूनिक्स सॉकेट ──► deckd
(वास्तविक TLS प्रमाणपत्र) (आपके उपयोगकर्ता के रूप में चलता है) (कार्य नाम) (रूट के रूप में चलता है)
│ │
hyprctl · pactl · ddcutil · grim · निश्चित अनुमति सूची
wf-recorder · uinput · WebRTC विशेषाधिकार प्राप्त कमांड
(cpupower, nvidia-smi,
systemctl, …)
दो प्रक्रियाएँ:
app/ — वेब ऐप आपके सामान्य उपयोगकर्ता के रूप में चलता है। यह वह सब कुछ करता है जिसके लिए रूट की आवश्यकता नहीं है: Hyprland नियंत्रण, ऑडियो, चमक, स्क्रीन कैप्चर, वर्चुअल इनपुट, WebRTC स्ट्रीमिंग, फ़ाइल स्थानांतरण।deckd/ — एक छोटा रूट सहायक (केवल stdlib, कोई निर्भरता नहीं) कुछ विशेषाधिकार प्राप्त कार्यों के लिए। वेब ऐप इसे कभी शेल स्ट्रिंग नहीं भेजता — केवल एक निश्चित अनुमति सूची से कार्य नाम (governor_performance, gpu_power_limit, suspend, …), जो किसी भी चीज़ को निष्पादित करने से पहले deckd/actions.py में मान्य किया जाता है। यहाँ तक कि अगर वेब ऐप पूरी तरह से समझौता कर लिया गया हो, तो विस्फोट त्रिज्या ठीक अनुमति सूची वाले कार्यों तक सीमित है, जिसमें कोई तर्क इंजेक्शन नहीं है। सॉकेट root:<group> मोड 0660 है।tailscale serve इसे आपके MagicDNS नाम पर एक वास्तविक Let's Encrypt प्रमाणपत्र के साथ उजागर करता है; यह कभी 0.0.0.0 से बाइंड नहीं होता है।वेब ऐप आपके कॉन्फ़िगर किए गए शेल कमांड चला सकता है और आपके उपयोगकर्ता के रूप में इनपुट इंजेक्ट कर सकता है — यह, डिज़ाइन के अनुसार, आपकी मशीन के लिए एक रिमोट कंट्रोल है। इसे अपने tailnet पर, PIN के पीछे रखें, और इसे सार्वजनिक रूप से उजागर न करें।
pactl/PulseAudio संगतता के साथ) के साथ लिनक्सhyprctl, pactl / pw-record / pw-play, playerctl, ddcutil,
wf-recorder, grim, cpupower, nvidia-smi, kitty (या आपका टर्मिनल)input समूह में ( के लिए) और समूह में ( के लिए)git clone <आपका-रेपो-यूआरएल> phone-deck
cd phone-deck
uv sync # .venv बनाता है और निर्भरताएँ स्थापित करता है
uv run python -m app.set_pin # अपना अनलॉक PIN सेट करें
deckd)पहले systemd/deckd.service संपादित करें — पथ और DECK_SOCKET_GROUP को एक समूह में सेट करें जिससे आपका उपयोगकर्ता संबंधित है (आमतौर पर आपका प्राथमिक समूह):
sudo cp systemd/deckd.service /etc/systemd/system/
sudo systemctl daemon-reload && sudo systemctl enable --now deckd
deckd सिस्टम Python चलाता है (केवल stdlib — कोई venv आवश्यक नहीं)।
विकास के लिए इसे सीधे चलाएँ:
uv run uvicorn app.main:app --host 127.0.0.1 --port 8765
…या उपयोगकर्ता सेवा के रूप में। पहले systemd/phone-deck.service पथ संपादित करें, फिर इसे स्थापित करें।
महत्वपूर्ण: एक सेटअप पर जहाँ Hyprland uwsm के माध्यम से लॉन्च नहीं किया जाता है, systemd graphical-session.target कभी सक्रिय नहीं होता है, इसलिए उपयोगकर्ता यूनिट लॉगिन पर स्वचालित रूप से प्रारंभ नहीं होगी। विश्वसनीय उपाय यह है कि इसे सत्र वातावरण आयात करते हुए Hyprland से प्रारंभ किया जाए — अपने Hyprland ऑटोस्टार्ट में जोड़ें (जैसे end-4 का ~/.config/hypr/custom/execs.conf):
exec-once = systemctl --user import-environment WAYLAND_DISPLAY HYPRLAND_INSTANCE_SIGNATURE XDG_RUNTIME_DIR DBUS_SESSION_BUS_ADDRESS XDG_CURRENT_DESKTOP && systemctl --user start phone-deck
प्रमाणपत्र एक बार सक्षम करें: Tailscale एडमिन कंसोल → DNS → Enable HTTPS Certificates.
ऐप को वास्तविक प्रमाणपत्र के साथ फ़्रंट करें:
sudo tailscale serve --bg 127.0.0.1:8765
HTTPS लाइव होने के बाद वेब-ऐप वातावरण में DECK_SECURE_COOKIES=1 सेट करें।
फ़ोन पर Chrome में https://<आपका-होस्ट>.<आपका-tailnet>.ts.net/ खोलें (यह आपके tailnet पर होना चाहिए), लॉग इन करें, फिर ⋮ → Install app। यह फ़ुलस्क्रीन, लैंडस्केप-लॉक, स्क्रीन को जागृत रखते हुए लॉन्च होता है। PWA सेवा वर्कर + वेक-लॉक के लिए HTTPS आवश्यक है।
किसी भी tailnet डिवाइस से काम करता है — लैपटॉप भी शामिल हैं (टच सतहें Pointer Events का उपयोग करती हैं, इसलिए माउस भी काम करता है)। WebRTC स्ट्रीम एकल-पीयर है (एक समय में एक दर्शक)।
सभी रनटाइम कॉन्फ़िग ~/.config/phone-deck/ में रहता है और Config टैब (JSON-सत्यापित, एक .bak रखता है) से संपादन योग्य है। परिवर्तन अगली कार्रवाई पर प्रभावी होते हैं — कोई पुनरारंभ नहीं।
commands.json — कस्टम शेल क्रियाएँ[
{ "id": "reload_wm", "label": "WM पुनः लोड करें", "run": "hyprctl reload" },
{ "id": "deploy", "label": "साइट परिनियोजित करें", "run": "cd /srv/app && ./deploy.sh",
"confirm": true, "timeout": 120 }
]
run एक स्ट्रिंग (bash -lc के माध्यम से निष्पादित) या एक सूची (argv, कोई शेल नहीं) हो सकता है। ये आपके उपयोगकर्ता के रूप में चलते हैं — यह एक स्थानीय, विश्वसनीय फ़ाइल है।
modes.json — दृश्य मैक्रोप्रत्येक मोड hyprctl के माध्यम से चलाए जाने वाले चरणों की एक क्रमबद्ध सूची है:
launch {cmd, workspace, match?, once?} — एक वर्कस्पेस पर एक ऐप खोलें। match (विंडो क्लास) + once के साथ, यह डुप्लिकेट नहीं होगा, और यदि विंडो गलत वर्कस्पेस पर आती है तो उसे स्थानांतरित करता है (ब्राउज़र PWA जैसे ऐप्स के लिए आवश्यक है जिनकी विंडो मौजूदा प्रक्रिया से आती है)।close {match, workspaces?} — एक क्लास की विंडो बंद करें, वैकल्पिक रूप से केवल सूचीबद्ध वर्कस्पेस पर।move {match, workspace} — मिलान करने वाली विंडो को एक वर्कस्पेस पर ले जाएँ।focus {workspace} — एक वर्कस्पेस को दृश्य में लाएँ (उदा. प्रत्येक मॉनिटर को उसके होम ws पर रीसेट करें)।मोड प्लेसमेंट केवल तभी नियतात्मक है जब आपके वर्कस्पेस मॉनिटर से पिन किए गए हों। अपने Hyprland कॉन्फ़िग में बाइंडिंग जोड़ें (अपने अनुसार वर्कस्पेस नंबर और मॉनिटर नाम समायोजित करें):
workspace = 1, monitor:DP-3, default:true
workspace = 2, monitor:DP-3
# … आदि
डेक एक फ़ॉस्फ़र-टर्मिनल त्वचा पहनता है जिसमें चार लाइव-स्विच करने योग्य रंग प्रोफ़ाइल हैं — हरा (डिफ़ॉल्ट), एम्बर, बर्फ, और ऑटो (आपके matugen वॉलपेपर पैलेट से फ़ॉस्फ़र रंग प्राप्त करता है, ~/.local/state/quickshell/user/generated/colors.json)। इसे System टैब में स्विच करें; चयन ~/.config/phone-deck/theme.json में बना रहता है। app/theme.py इसे /theme.css के रूप में परोसता है। परिवेश विचारक का निष्क्रिय समय और संस्कार पंक्ति भी यहाँ कॉन्फ़िगर करने योग्य है।
द्विदिश WebRTC aiortc + PyAV के माध्यम से, सबप्रोसेस पाइप (नाजुक डिवाइस-I/O बाइंडिंग से बचता है) के साथ PipeWire/Hyprland से जुड़ा:
parec के साथ डिफ़ॉल्ट सिंक के .monitor को कैप्चर करें → Opus।wf-recorder एक मॉनिटर को कैप्चर करता है → aiortc, गुणवत्ता प्रीसेट (540p / 720p / 1080p) के साथ ताकि कमजोर लिंक पर बिटरेट सामान्य रहे।hyprctl movecursor) + uinput क्लिक। टैप = क्लिक, ड्रैग = मूव, लॉन्ग-प्रेस = राइट-क्लिक।बाधाएँ: ~150–300 ms विलंबता; केवल तभी विश्वसनीय जब PWA अग्रभूमि में हो (एंड्रॉइड पृष्ठभूमि टैब को निलंबित करता है); इको से बचने के लिए हेडफ़ोन का उपयोग करें; एक समय में एक स्ट्रीमिंग पीयर; ब्राउज़र फ़ोन के अपने ऐप ऑडियो को कैप्चर नहीं कर सकता (केवल माइक)।
tailscale serve)uv run pytest
deckd अनुमति सूची, JWT + लॉगिन लॉकआउट, PIN हैशिंग, कॉन्फ़िग-एडिटर सत्यापन, मोड पार्सिंग, स्ट्रीमिंग गुणवत्ता/कमांड तर्क, और इनपुट कीमैप को कवर करता है। लाइव WebRTC/PipeWire/Hyprland पथ विकास के दौरान लूपबैक द्वारा मान्य किए जाते हैं।
app/ FastAPI वेब ऐप
main.py रूट + WebSockets
hypr.py Hyprland (स्नैपशॉट, डिस्पैच, इवेंट सॉकेट, कर्सर)
audio.py PipeWire डिवाइस नियंत्रण + playerctl
audio_rtc.py WebRTC ऑडियो + स्क्रीन वीडियो ब्रिज
hid.py uinput के माध्यम से वर्चुअल कीबोर्ड/माउस
modes.py दृश्य-मैक्रो इंजन
brightness.py ddcutil
grab.py स्क्रीनशॉट + फ़ाइल अपलोड
theme.py matugen → CSS
...
deckd/ रूट सहायक (केवल stdlib) + कार्य अनुमति सूची
systemd/ सेवा इकाइयाँ
tests/ pytest सूट
MIT — LICENSE देखें (यदि आप एक अलग लाइसेंस चाहते हैं तो प्रकाशित करने से पहले एक जोड़ें)।
Hyprland, PipeWire, Tailscale, aiortc, और end-4 डॉटफ़ाइल्स के लिए बनाया गया।
/dev/uinputi2cddcutilaiortc + PyAV (uv के माध्यम से स्थापित)