كيف وُلد كالو
2026-07-03
بدأت بمشكلة لم أستطع حلّها بنظافة
قبل فترة — قبل أن يصبح الذكاء الاصطناعي أداة نلجأ إليها كل يوم — كنت أعمل على مشروع Flutter يحتاج إلى مكالمات SIP صوتية حقيقية. ليست محادثة فيديو، ولا عرضًا في متصفّح: مكالمات أصلية صريحة قادرة على التحدّث إلى بنية اتصالات قائمة. بحثت عن شيء جاهز أضيفه، فعدت خالي الوفاض تقريبًا. كل شيء تقريبًا كان يقودني نحو WebRTC، و WebRTC ببساطة لم يكن يناسب حاجتي. إنه مصمَّم لمشكلة مختلفة، وليّ ذراعه نحو SIP الأصلي كان أشبه بمصارعة الأداة في كل خطوة.
ففعلت الأمر العملي. وجدت محرّك SIP أصليًا — ناضجًا وقادرًا — وبنيت فوقه طبقة Flutter كي يتمكّن تطبيقي فعلًا من إجراء المكالمات. ونجح الأمر. لكن التجربة تركت في ذهني شوكة لم أستطع نزعها تمامًا.
الشوكة: هذا أكثر ممّا أحتاج، ويكلّف أكثر ممّا ينبغي
المحرّك الذي بنيت عليه كان قويًّا، وهذا جزء من المشكلة. كان يأتي بأكثر بكثير ممّا طلبته حالتي يومًا — كمّ هائل من الميزات لن ألمس معظمها — ومعه بنية تكلفة لا معنى لها لما كنت أفعله فعلًا. ظللت أنظر إليه وأفكّر: أحمل كل هذا الثقل وأدفع مقابل كل هذه القدرات لأنجز أمرًا واحدًا محدَّدًا نسبيًّا.
هنا ظهرت الفكرة لأول مرّة، تلك التي لا تغادرك تمامًا بعد أن تصل: لماذا لا أبني واحدًا خاصًّا بي؟ شيء رشيق. شيء مصمَّم تمامًا على شكل المشكلة، لا عشر مشكلات بجانبها. شيء أفهمه من طرفه إلى طرفه.
الجدار: لم أكن أملك معرفة C
المشكلة أنّ "أبني واحدًا خاصًّا بي" اصطدم مباشرة بجدار. العمل الحقيقي في SIP الأصلي يقبع في أعماق لغة C — ذلك النوع من الشيفرة منخفضة المستوى الحذِرة مع الذاكرة، والتي لم أكتبها ببساطة. كان بوسعي تصميم واجهة Dart أنيقة طوال اليوم، لكنّ المحرّك تحتها كان لغةً وانضباطًا لا أملكهما. ففعلت الفكرة ما تفعله كثير من الأفكار الجيدة: ذهبت إلى الرفّ. لم تُهجَر، بل... رُكِنت. كنت أنزلها بين حين وآخر، أنظر إليها، ثم أعيدها.
نقطة التحوّل
ما تغيّر لم يكن أنني تعلّمت C فجأة في عطلة نهاية أسبوع. ما تغيّر أنّ أدوات الذكاء الاصطناعي صارت جيدة بما يكفي لجعل الفجوة قابلة للعبور. لا مُلغاة — بل قابلة للعبور. فجأة صار الأمر الذي عطّلني طويلًا شيئًا أستطيع الاقتراب منه فعلًا: أستطيع أن أتفهّم شيفرة أصلية غير مألوفة، وأطرح الأسئلة في وسطها، وأحرز تقدّمًا حيث كنت سأتوقّف سابقًا بلا تردّد. قرّرت أن أكفّ عن التنظير وأن أجرّب فحسب، وأرى إلى أين يقودني ذلك.
الجزء الصادق: لم يكن الأمر "اكتب أمرًا وانسَه"
أريد أن أكون واضحًا في هذا، لأنّ النسخة السهلة من هذه القصة كذبة. لم يكن الأمر كتابة أمر واستلام حزمة جاهزة. كان مسارًا طويلًا من التجربة والخطأ — بناءات لا تعمل، ومكالمات تتّصل لكنها تبقى صامتة، ومشكلات دقيقة تطلّب فهمها وإصلاحها وقتًا حقيقيًّا. كان الذكاء الاصطناعي مُسرِّعًا حقيقيًّا، لكنني بقيت أنا مَن يوجّه ويختبر ويتّخذ القرارات.
وفي الطريق تعلّمت كومة من الأشياء لم أفعلها من قبل. أنشأت خادم SIP خاصًّا بي كي يكون لديّ شيء حقيقي أختبر عليه. تعلّمت كيف أتحقّق فعلًا من تسجيل المكالمات، ومن تدفّق الصوت في الاتجاهين، ومن أنّ الإشارات والوسائط تفعل ما تدّعيه. وتعلّمت الحرفة غير اللامعة: نشر حزمة حقيقية يستطيع مطوّرون آخرون الاعتماد عليها — التحزيم، والإصدارات، وانضباط شحن شيء عليه أن يستمرّ في العمل. لا شيء من ذلك برّاق، وكلّه كان مهمًّا.
أين استقرّ الأمر
النتيجة هي كالو: حزمة Flutter مغلقة لمكالمات SIP الصوتية الأصلية، على أندرويد و iOS معًا، مؤمَّنة بـ TLS و SRTP، تُسلَّم كحزمة واحدة تعمل على المنصّتين ببساطة. وهي الآن عند إصدار مستقرّ 0.1.16 — نسخة أشعر فعلًا بالارتياح لعرضها أمام الناس. وهناك بوابة فيها التوثيق والترخيص كي يطلب المطوّر الوصول ويبدأ دون حاجة إليّ في الوسط.
لن أبالغ في وصف ما وصل إليه. إنه مبكّر، وصادق في ذلك. لكنه موجود، ومستقرّ، ويفعل الأمر المحدَّد الذي بحثت عنه يومًا ولم أجده: مكالمات أصلية حقيقية في Flutter، دون أن تحمل منصّة اتصالات كاملة لتحصل عليها.
إن كنت تبني بـ Flutter وسبق أن احتجت مكالمات صوتية كما ينبغي، فيسعدني أن تجرّبه. تجد التوثيق وتطلب الوصول عبر kallosdk.com.