بث مباشر 18.11 · الدفعة 318 نوفمبر، 19:00 بتوقيت موسكو — ورشة عملية مجانية لوكلاء الذكاء الاصطناعي · الدفعة 3 تبدأ 23.11ورشة 18 نوفمبر ←الدفعة 3 (23.11)
إصدارتحليل · على الرادارHabr AI→ المصدر

مطوّر يصنع تميمة لـ Claude Code تدقّ الأرض بقدميها بينما ينتظر المساعد الرد

كثيرًا ما تنتهي مهمة طويلة في Claude Code بأن ينتظر الوكيل عشر دقائق سؤال «هل يمكن تنفيذ الأمر؟»، بينما لم يومض إشعار Windows سوى خمس ثوانٍ ثم اختفى. صنع المؤلف تميمة مفتوحة المصدر على Electron: تطل من زاوية الشاشة، وإذا تجاهلتها احمرّت ودقّت الأرض بقدميها على شريط المهام. تُؤخذ الإشارة من hooks في Claude Code ومن قاعدة إشعارات Windows.

معالج بواسطة الذكاء الاصطناعي من Habr AI؛ بتحرير Hamidun News
مطوّر يصنع تميمة لـ Claude Code تدقّ الأرض بقدميها بينما ينتظر المساعد الرد
المصدر: Habr AI. كولاج: Hamidun News.
استمع للمقال
بطاقة الحقائق والأرقام
المعيارالتفاصيل
المصدر الأصليHabr AI ↗
رئيس التحرير
حقيقة رئيسية #1يرسل hook من نوع Notification في settings.json الحدث إلى منفذ HTTP محلي
حقيقة رئيسية #2يتطلب تطبيق سطح المكتب PermissionRequest وPreToolUse إضافةً إلى قراءة wpndatabase.db
الكود بترخيص MIT، والتقنياتElectron وnode:sqlite وkoffi دون node-gyp

موقف مألوف: تعطي Claude Code مهمة كبيرة، وتنتقل إلى النافذة المجاورة، وبعد ربع ساعة تكتشف أن الوكيل توقف منذ وقت طويل عند سؤال «هل يمكن تنفيذ هذا الأمر؟». إشعار Windows النظامي ظهر بالطبع، لكنه بقي خمس ثوانٍ في زاوية الشاشة بينما كنت تنظر إلى مكان آخر. قرّر مؤلف المقال على Habr حل المشكلة جذريًا: صنع تميمة يستحيل ألا تلاحظها.

التميمة رجل برتقالي صغير. يطلّ أولًا من الزاوية اليمنى السفلى. وإذا تجاهلته يخرج بالكامل، ويحمرّ، ويدقّ الأرض بقدميه على شريط المهام حتى تعود. الغلاف طريف، لكن الأكثر فائدة هنا هو الجانب الهندسي: كيف تعرف بموثوقية أن المساعد ينتظر شيئًا.

كيف نلتقط لحظة الانتظار

في نسخة الطرفية من Claude Code الأمر بسيط بفضل الـ hooks. يمكن في ‎~/.claude/settings.json‎ وصف أمر يُشغَّل عند الحدث المطلوب، ويصله JSON بالتفاصيل عبر stdin. يناسب هذه المهمة حدث Notification. يرسل الأمر محتوى stdin عبر curl إلى خادم HTTP المحلي الخاص بالتميمة (127.0.0.1:47821). الذيل || exit 0 ضروري كي ينتهي الـ hook بصمت برمز صفر إذا لم تكن التميمة قيد التشغيل، فلا يعرض Claude Code خطأً عند كل حدث. كما يرفض الخادم الطلبات التي تحمل ترويسة Origin، حتى لا تتمكن صفحة ويب عشوائية من العبث بالمنفذ المحلي.

مع تطبيق Claude لسطح المكتب (تبويب Code) الأمر أصعب: عندما يطلب إذنًا أو يطرح سؤالًا لا يُرسَل حدث Notification. في الطرفية كان كل شيء يعمل، أما على سطح المكتب فكانت التميمة صامتة. اضطر المؤلف إلى الاشتراك أيضًا في PermissionRequest وفي PreToolUse مع matcher بالقيمة AskUserQuestion|ExitPlanMode لالتقاط الأسئلة والموافقة على الخطة. وهناك اختياريًا Stop الذي يعمل بعد كل رد. تسجّل التميمة الـ hooks بنفسها، بعد أخذ نسخة احتياطية من settings.json (تُحفظ آخر خمس نسخ) ودون المساس بإدخالات الآخرين.

ثمة تفصيل مهم: قد لا تلتقط الجلسات المفتوحة بالفعل الـ hooks الجديدة قبل إعادة التشغيل. لذلك أُضيف مصدر ثانٍ للإشارة هو قاعدة إشعارات Windows. يكتب النظام كل لافتة إشعار في ملف SQLite باسم wpndatabase.db. مرة كل ثانية تفتحه التميمة للقراءة وتبحث عن سجلات التطبيق بالصيغة ‎Claude_*!Claude‎. تغني وحدة node:sqlite المدمجة في Node عن التبعيات الأصلية، وتعمل هذه الطريقة حتى مع Claude المشغَّل أصلًا، دون حقن أي شيء فيه.

نافذة مرئية لكنها لا تزعج

المهمة الثانية رسم الطبقة العلوية (overlay). يجب أن تكون شفافة، وفوق جميع النوافذ (بما فيها ملء الشاشة)، ولا تظهر في شريط المهام، ولا تسرق التركيز، وتمرّر النقرات من خلالها. في Electron يتعلق الأمر تقريبًا كليًا بإعدادات BrowserWindow: ‎frame: false‎ و‎transparent: true‎ و‎skipTaskbar‎ و‎alwaysOnTop‎ و‎focusable: false‎.

حيلة مثيرة: ‎setIgnoreMouseEvents(true, { forward: true })‎. تصبح النافذة شفافة للنقرات، لكن الصفحة تظل تتلقى أحداث حركة الفأرة. عندما يدخل المؤشر على التميمة (mouseenter) تُفعَّل النقرات من جديد، وعند خروجه تُعطَّل. لا حاجة لحساب شكل النافذة يدويًا.

لمعرفة ما إذا كانت نافذة Claude نشطة وإعادتها إلى الواجهة يستخدم المؤلف koffi: فهو يستدعي دوال user32.dll دون node-gyp. تُستطلع النافذة النشطة كل 300 مللي ثانية، ولا يُلاحَظ أي حِمل.

تفاصيل صغيرة تستحق الاقتباس

إذا ظهرت التميمة ولافتة Windows القياسية في وقت واحد يحدث تكرار. لهذا يوجد خيار يعطّل اللافتات لـ Claude وحده عبر ‎ShowBanner = 0‎ في السجل (registry). تبقى السجلات في مركز الإشعارات، فتستمر القاعدة في الامتلاء وترى التميمة الإشعارات. يُحفظ المعيار السابق للإعداد ويُستعاد عند تعطيل الخيار، وعند الخروج، وعند إنهاء الجلسة، وحتى بعد انهيار مفاجئ عند التشغيل التالي.

ومن عقبات البناء التي ذكرها المقال: يرفع electron-builder الملفات بالتوازي وأحيانًا ينشئ نسخًا مكررة من الإصدار، لذلك يُنشأ الإصدار في GitHub Actions أولًا عبر ‎gh release create‎ ثم يُملأ. وفي النسخة المحمولة (portable) يشير ‎process.execPath‎ إلى مجلد مؤقت، لذا يؤخذ المسار للتشغيل التلقائي من المتغير PORTABLE_EXECUTABLE_FILE.

ماذا نفعل بهذا

المشروع مجاني، بترخيص MIT، لنظام Windows. وحتى إن لم تنوِ تثبيت التميمة، فالنمط نفسه مفيد: hook من نوع Notification مع مستقبِل HTTP محلي هو أبسط طريقة لربط Claude Code بأي إشارة خارجية، سواء كانت صوتًا أو هاتفًا أو مصباحًا ذكيًا. القيد الرئيسي: الحل مرتبط بنظام Windows وبالصيغة الداخلية لقاعدة الإشعارات التي لا توثّقها Microsoft بوصفها API. وبالنسبة إلى Claude لسطح المكتب يُعدّ هذا المصدر احتياطيًا وقد يتعطل مع تحديث النظام. أما لنسخة الطرفية فتكفي الـ hooks.

القصة

أسئلة وأجوبة حول الخبر

ما أبرز التفاصيل حول كيف نلتقط لحظة الانتظار؟

في نسخة الطرفية من Claude Code الأمر بسيط بفضل الـ hooks. يمكن في ‎~/.claude/settings.json‎ وصف أمر يُشغَّل عند الحدث المطلوب، ويصله JSON بالتفاصيل عبر stdin. يناسب هذه المهمة حدث Notification. يرسل الأمر محتوى stdin عبر curl إلى خادم HTTP المحلي الخاص بالتميمة (127.0.0.1:47821). الذيل || exit 0 ضروري كي ينتهي الـ hook بصمت برمز صفر إذا لم تكن التميمة قيد التشغيل، فلا يعرض Claude Code خطأً عند كل حدث. كما يرفض الخادم الطلبات التي تحمل ترويسة Origin، حتى لا تتمكن صفحة ويب عشوائية من العبث بالمنفذ المحلي.

ما أبرز التفاصيل حول نافذة مرئية لكنها لا تزعج؟

المهمة الثانية رسم الطبقة العلوية (overlay). يجب أن تكون شفافة، وفوق جميع النوافذ (بما فيها ملء الشاشة)، ولا تظهر في شريط المهام، ولا تسرق التركيز، وتمرّر النقرات من خلالها. في Electron يتعلق الأمر تقريبًا كليًا بإعدادات BrowserWindow: ‎frame: false‎ و‎transparent: true‎ و‎skipTaskbar‎ و‎alwaysOnTop‎ و‎focusable: false‎. حيلة مثيرة: ‎setIgnoreMouseEvents(true, { forward: true })‎. تصبح النافذة شفافة للنقرات، لكن الصفحة تظل تتلقى أحداث حركة الفأرة.

ما أبرز التفاصيل حول تفاصيل صغيرة تستحق الاقتباس؟

إذا ظهرت التميمة ولافتة Windows القياسية في وقت واحد يحدث تكرار. لهذا يوجد خيار يعطّل اللافتات لـ Claude وحده عبر ‎ShowBanner = 0‎ في السجل (registry). تبقى السجلات في مركز الإشعارات، فتستمر القاعدة في الامتلاء وترى التميمة الإشعارات. يُحفظ المعيار السابق للإعداد ويُستعاد عند تعطيل الخيار، وعند الخروج، وعند إنهاء الجلسة، وحتى بعد انهيار مفاجئ عند التشغيل التالي.

ZK
جمال حميدون — مدير المنتجات في Alpina Digital ومدير منتج AlpinaGPT. يبني منتجات الذكاء الاصطناعي منذ 2019. بدأ Hamidun News كمشروع شخصي ثم أصبح مُجمِّعًا إنتاجيًا بأكثر من 6000 قارئ.
✦ Hands-On AI Engineering · Hamidun Academy

Build & Ship Production AI Agents Without Boilerplate Code

Start your free 72-hour trial at Hamidun Academy (academy.hamidun.com) — interactive lessons on Claude Code & Cursor, live Tech Radar, and production agent templates.

Start 72h Free Trial →Vibe-Coding Intensive
ما رأيك؟
جارٍ تحميل التعليقات…