
منصة تحكم ذاتية الاستضافة وسطح مكتب عن بعد لمحطات عمل لينكس عبر Tailscale، مع بث WebRTC، التحكم الصوتي باستخدام LLM محلي، وحدات ماكرو للمشاهد، إدخال افتراضي، نقل الملفات، وقياس حيوي للنظام.
حوّل هاتف Android احتياطي (أو أي جهاز بمتصفح) إلى لوحة تحكم مستضاف ذاتياً وسطح مكتب بعيد لمحطة عمل Linux الخاصة بك — عبر شبكة Tailscale الخاصة بك، دون أي تطبيقات طرف ثالث.
لقد بدأ الأمر كسؤال «ماذا أفعل بهاتف قديم؟» وأصبح طبقة تحكم لنظام Hyprland: التحكم في النوافذ/مساحات العمل، وحدات الماكرو للمشاهد، موجه صوت بالضغط للتحدث مع مساعد LLM محلي، تحكمات سياقية داخل التطبيق، بث صوتي + شاشة ثنائي الاتجاه، سطح مكتب بعيد يعمل باللمس، لوحة مفاتيح/فأرة افتراضية، نقل الملفات + مشاركة من الهاتف إلى الحاسوب، وقياسات حية — كل ذلك يُقدّم كتطبيق ويب تقدمي (PWA) مثبت بمظهر طرفي فوسفوري.
ملاحظة حول قابلية النقل. بني هذا الإعداد لإعداد محدد: Linux قائم على Arch (Garuda) + Hyprland + PipeWire + NVIDIA + Tailscale، مع ملفات نقطة end-4 / illogical-impulse. البنية عامة، لكن العديد من التكاملات خاصة بالبيئة (أسماء الشاشات، ربط مساحات العمل، مسار ثيم matugen،
cpupower/nvidia-smi). عامله كمرجع عملي للتكييف، وليس كحزمة جاهزة.
الواجهة هي تطبيق ويب داكن، أفقي، مع علامات تبويب (متزامن مع ثيم سطح المكتب):
| التبويب | ما يفعله |
|---|---|
| مساحات العمل (Workspaces) | شبكة مساحات عمل حية لكل شاشة (اضغط للتبديل)، قائمة نوافذ حية (اضغط للتركيز)، تبديل DPMS لكل شاشة + سطوع ddcutil |
| التحكم عن بُعد (Remote) | لوحة لمس على الشاشة (سحب/نقر/إصبعين) + لوحة مفاتيح افتراضية مع معدّلات واختصارات، عبر جهاز uinput kernel |
| الأنماط (Modes) | وحدات ماكرو مشهد بنقرة واحدة — تشغيل/إغلاق/ترتيب تخطيطات تطبيقات كاملة عبر الشاشات (مثل «عمل» / «حر») |
| الصوت (Voice) | موجه صوت بالضغط للتحدث (faster-whisper، CPU): مسارات كلمة رئيسية — macro (تشغيل نمط/أمر)، type (إملاء)، input (عبارة → سلسلة مفاتيح) — مع تأكيد قبل التنفيذ، بالإضافة إلى «friday»، مجيب LLM محلي للقراءة فقط (Ollama + Qwen) مع بحث ويب مستضاف ذاتياً ووعي بحالة النظام الحية |
| الصوتيات (Audio) | كتم الميكروفون/مكبر الصوت، مستوى الصوت، منتقي أجهزة الإخراج والإدخال، نقل playerctl + غلاف الألبوم (يتتبع مشغل MPRIS النشط) |
| البث (Stream) | صوت WebRTC ثنائي الاتجاه (الحاسوب ↔ الهاتف، مع استخدام الهاتف كميكروفون وإخراج للهاتف فقط) + فيديو الشاشة، واضغط للتحكم في الشاشة المُبثَّة = سطح مكتب بعيد حقيقي |
| النظام (System) | تبديل وضع الأداء، تبديل الثيم الحي، حالة Tailscale، العمليات العليا (اضغط للقتل)، القفل، إعادة تشغيل NetworkManager، الإسبات/إعادة التشغيل/إيقاف التشغيل |
| الملفات (Files) | التقط لقطة شاشة لشاشة → عرض/تنزيل على الهاتف؛ إسقاط ملف من الهاتف إلى الحاسوب |
| الإعدادات (Config) | تحرير ملفات الإعدادات commands.json / modes.json (والسياق والصوت) من الهاتف (تم التحقق من JSON) |
دائماً في الأعلى، فوق علامات التبويب — شريط سياق يعرض ما يحدث الآن: مكالمة نشطة (كتم / الانتقال إليها)، وسائط قيد التشغيل + النقل، وتحكمات لوحة المفاتيح داخل التطبيق للتطبيق المركز (YouTube / Brave / Teams)، تُقدّم دون سرقة التركيز.
اثنان آخران، خارج علامات التبويب:
بالإضافة إلى: تسجيل دخول PIN بلوحة أرقام على الشاشة، قفل الشاشة من الاستيقاظ، PWA أفقي ملء الشاشة، وقفل الدخول بعد محاولات متكررة على تسجيل الدخول.
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, …)
عمليتان:
app/ — تطبيق الويب يعمل كمستخدمك العادي. يقوم بكل ما لا يحتاج صلاحيات الجذر: التحكم في Hyprland، الصوت، السطوع، التقاط الشاشة، الإدخال الافتراضي، بث WebRTC، نقل الملفات.deckd/ — مساعد جذر صغير (مكتبة قياسية فقط، بلا تبعيات) للإجراءات القليلة التي تحتاج صلاحيات. لا يرسل تطبيق الويب له سلاسل شل أبداً — بل فقط أسماء إجراءات من قائمة مسموحة ثابتة (governor_performance، gpu_power_limit، suspend، …)، تم التحقق منها في deckd/actions.py قبل تنفيذ أي شيء. حتى لو تم اختراق تطبيق الويب بالكامل، فإن نصف قطر الانفجار هو بالضبط الإجراءات المسموحة، دون أي حقن وسيط. المقبس هو root:<group> في الوضع 0660.tailscale serve يعرضه على اسم MagicDNS الخاص بك مع شهادة Let's Encrypt حقيقية؛ لا يرتبط أبداً بـ 0.0.0.0.يمكن لتطبيق الويب تشغيل أوامر الشل المُهيئة وحقن الإدخال كمستخدمك — فهو، بالتصميم، جهاز تحكم عن بُعد لجهازك. احتفظ به على شبكة ذيلك، خلف PIN، ولا تعرضه للجمهور.
pactl/توافق PulseAudio)hyprctl, pactl / pw-record / pw-play, playerctl, ddcutil,
wf-recorder, grim, cpupower, nvidia-smi, kitty (أو محطة طرفية)input (لـ /dev/uinput) ومجموعة i2c (لـ ddcutil)aiortc + PyAV (مثبت عبر uv) لبث الصوت/الفيديوgit clone <your-repo-url> 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 (مكتبة قياسية فقط — لا حاجة لـ venv).
شغّله مباشرة للتطوير:
uv run uvicorn app.main:app --host 127.0.0.1 --port 8765
…أو كخدمة مستخدم. حرّر مسارات systemd/phone-deck.service أولاً، ثم ثبّته.
مهم: في إعداد يتم فيه تشغيل Hyprland ليس عبر uwsm، لا يتم تنشيط graphical-session.target لنظام systemd، لذا لن تبدأ وحدة المستخدم تلقائياً عند تسجيل الدخول. الإصلاح الموثوق هو بدء تشغيله من Hyprland مع استيراد بيئة الجلسة — أضف إلى بدء التشغيل التلقائي لـ Hyprland (مثلاً ~/.config/hypr/custom/execs.conf في end-4):
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
عيّن DECK_SECURE_COOKIES=1 في بيئة تطبيق الويب بمجرد تفعيل HTTPS.
افتح https://<your-host>.<your-tailnet>.ts.net/ في Chrome على الهاتف (يجب أن يكون على شبكة ذيلك)، سجل الدخول، ثم ⋮ → Install app. ينطلق بملء الشاشة، بقفل أفقي، مع إبقاء الشاشة مستيقظة. HTTPS مطلوب لمستخدم الخدمة العاملة PWA + قفل الاستيقاظ.
يعمل من أي جهاز في شبكة الذيل — بما في ذلك أجهزة الكمبيوتر المحمولة (تستخدم أسطح اللمس أحداث المؤشر، لذا يعمل الفأرة أيضاً). بث WebRTC هو نظير واحد (مشاهد واحد في كل مرة).