ثقب الموارد في Claude Code: من حزمة ملف واحد بحجم 11.3 ميغابايت إلى استهلاك قرص يصل إلى 1.2 تيرابايت
Categories:
عميل Claude Code هو تطبيق Node.js ملف واحد بدون إدارة دورة حياة الموارد: عند بدء التشغيل يتم تحليل ملف حزمة بحجم 11.3 ميغابايت، وفي وقت التشغيل يكتب إلى القرص بلا حدود، وبعد إغلاق الطرفية يظل العملية حية وتستمر في استهلاك الذاكرة حتى يتعطل النظام. استنادًا إلى تقارير المستخدمين الحقيقية على GitHub Issues وتحليل المجتمع العكسي، نستعرض في هذا المقال عيوب إدارة الموارد في الذاكرة، وحدة المعالجة المركزية، والقرص، مكشوفين مشكلات بنية الحزمة، تصميم التخزين، وإدارة دورة حياة العملية. هذه ليست حالات طرفية، بل مشكلات بنية متكررة تم الإبلاغ عنها من أغسطس 2025 حتى أبريل 2026، وتم إغلاقها جماعيًا بواسطة روبوت stale.
بنية الحزمة: تكلفة ملف واحد بحجم 11.3 ميغابايت
نواة Claude Code هي ملف واحد يُدعى cli.js بحجم تقريبًا 11.3 ميغابايت. قام المستخدم المجتمعي paultendo بتحليل ثابت مفصل في Issue #29481، كاشفًا عدة مشكلات بنية خطيرة.
زمن بدء تشغيل V8: 32% من الوقت للتحليل
أظهر ملف تعريف CPU أن compileSourceTextModule استهلك 31.7% من وقت العينة في مرحلة البدء. يحتاج محرك V8 حوالي 300 مللي ثانية لتحليل هذا الملف الواحد بحجم 11.3 ميغابايت، بينما يستغرق تحليل سكريبت Node.js عادي 23 مللي ثانية فقط. استهلك 7.3% إضافية في استدعاء spawnSync، و3.5% في جمع القمامة. هذا يعني أنه قبل أن يدخل المستخدم أي أمر، تم إهدار أكثر من 40% من زمن البدء في مجرد التحليل.
التحميل الكامل: 20 استيرادًا ديناميكيًا فقط
يتم تحليل وتنفيذ ملف الحزمة بالكامل عند البدء، مع وجود 20 تعبيرًا import() فقط. يدفع كل مستخدم تكلفة جميع الوظائف بغض النظر عن استخدامها. إليكم المكونات التي يجب أن تُحمَّل عند الطلب ولكن تم تضمينها بالكامل:
pie title مكونات ملف الحزمة (≈ 13.5 ميغابايت)
"منطق التطبيق الأساسي" : 7540
"AWS Bedrock SDK" : 1100
"highlight.js (182 لغة)" : 1000
"OpenTelemetry" : 900
"Google Vertex + gRPC + Protobuf" : 800
"RxJS" : 300
"أخرى (Ink, Zod, Ajv, Axios وغيرها)" : 1807مساعد الترميز يحتاج إلى تمييز 182 لغة مثل Brainfuck، MIPS assembly، Flix، Zephir، Inform7، Lasso وغيرها، وهذا يوضح مدى السطحية في استراتيجية الحزم. الاحتفاظ بـ 40 لغة شائعة فقط يمكن أن يوفر حوالي 786 كيلوبايت من تكلفة التحليل.
تبذير الاعتمادات: أربعة عملاء HTTP، ثلاث مكتبات تحقق
كل SDK يجلب اعتماده المستقل، مما يؤدي إلى وجود أربعة عملاء HTTP (Axios، Undici، Got، fetch الأصلي) وثلاث مكتبات تحقق (Zod، Ajv، JSON Schema) في ملف الحزمة. في بيئة Node 18+، fetch الأصلي متاح تمامًا ولا حاجة لعملاء HTTP إضافيين.
413 استدعاء نظام ملفات متزامن
يحتوي ملف الحزمة على 196 استدعاء existsSync، 109 استدعاء statSync، 108 استدعاء readFileSync، 58 استدعاء mkdirSync وغيرها، مجموعها 413 استدعاء متزامن. كل واحد منها يعيق حلقة الحدث. كثير من الاستدعاءات تتبع نمط existsSync(path) && readFileSync(path)، ويمكن استبداله بنمط واحد try { await readFile(path) } catch {}.
1087 غلافًا لتوافقية CJS/ESM
كل وحدة CommonJS تُدمج في ESM تُولِّد غلافًا __toESM/__commonJS/__require، مجموعها 1087 غلافًا. هذه الأغلفة تزيد من وزن التحليل وتضيف حمولة تشغيلية صغيرة لكل وحدة.
polyfill غير ضروري لـ Node 20
يحتوي ملف الحزمة على 62 غلاف Promise (مدعومة أصلاً منذ Node 0.12)، 57 غلاف Symbol (من Node 4)، 57 دالة مساعدة async (من Node 8)، و3 polyfill لـ AbortController (من Node 15). هذه الاعتمادات جاءت من تبعيات تمريرية مخصصة لإصدارات Node أو المتصفحات القديمة، وهي غير ضرورية في بيئة التشغيل المستهدفة.
تضمين جميع ثنائيات ripgrep لـ 6 منصات: 61 ميغابايت
تم تضمين جميع ثنائيات ripgrep لـ 6 منصات، مجموعها 61 ميغابايت. بالمقابل، يستخدم sharp الاعتمادات الاختيارية لتثبيت الثنائي المناسب فقط للمنصة الحالية، مما يوفر حوالي 51 ميغابايت من مساحة القرص لكل تثبيت.
تدهور أداء Ink مع طول المحادثة
واجهة الطرفية تستخدم Ink (React for Terminal). أظهر التحليل وجود 6457 استدعاء createElement، 578 هوك useState، ولكن فقط 11 غلاف React.memo()، بنسبة 1.9% فقط. في Ink، كل تحديث حالة يُعيد تنسيق شجرة DOM الافتراضية بالكامل. أثناء الاستجابة المتدفقة، كل رمز يُسبب تحديث حالة، مما يؤدي إلى إعادة رسم غير ضرورية للمكونات غير الممّوَّزة. مع زيادة طول المحادثة، يزداد حجم الإخراج، وتحتاج كل إعادة رسم إلى مقارنة (diff) المزيد من محتوى الطرفية. هذا يتطابق مع الظاهرة المبلغ عنها في Issue #22265 بعنوان “المحادثة تصبح أبطأ مع تقدمها”.
استهلاك القرص: من جيجابايت إلى تيرابايت بنمو غير محدود
مشكلة القرص هي أخطر عيب في إدارة موارد Claude Code، وتؤثر على أوسع نطاق وتسبب أسوأ العواقب.
تسرب وحدة .node الأصلية على Windows: 20 جيجابايت أسبوعيًا
يسجل Issue #23095 مشكلة مستمرة لعدة أشهر: ملف الثنائي الأصلي لـ Windows (claude.exe) ينسخ مكوّن Node.js الأصلي إلى دليل مؤقت في كل جلسة دون تنظيفه. كل ملف يبلغ حجمه 6.6 ميغابايت؛ جمع المستخدم SlothKing16 2813 ملفًا في 4 أيام، أي ما مجموعه 18 جيجابايت. إحصاءات المستخدم kolkov أكثر صدمة: حوالي 20 جيجابايت أسبوعيًا، ويمكن للمستخدمين المكثفين الوصول إلى 100 جيجابايت أسبوعيًا. تم الإبلاغ عن هذه المشكلة منذ أوائل 2025، وتم وسمها كمتكررة وإغلاقها آليًا بواسطة الروبوت.
دليل ~/.claude: أكثر من 3 جيجابايت دون إدارة
قام المستخدم kolkov بتدقيق جهاز يستخدم Claude Code بانتظام لمدة 8 أشهر في Issue #5024:
pie title استهلاك دليل ~/.claude (≈ 3.1 جيجابايت)
"projects/ (سجلات الجلسات)" : 2500
"debug/ (سجلات التصحيح)" : 303
"file-history/ (لقطات الملفات)" : 232
"history.jsonl (السجل العام)" : 10
"أخرى" : 55الأرقام الرئيسية: أكبر ملف JSONL لجلسة واحدة 203 ميغابايت، أكبر ملف فرعي 72 ميغابايت، history.jsonl يحتوي على أكثر من 37000 مدخل. لا توجد تدوير للبيانات، ولا ضغط، ولا آلية تنظيف. لا تُزيل النسخ المتكررة في file-history/؛ كل تعديل للملف يُخزن نسخة كاملة. ولا يتم تنظيف سجلات debug/.
ملفات إخراج المهام الخلفية: حلقة ميتة ذات إشارة ذاتية تصل إلى 1.2 تيرابايت
يكشف Issue #32282 عن عيب تصميم مذهل. عندما يطلق Claude Code عدة وكلاء خلفية ويشغّل أمر Bash يتحقق من التقدم، يُكتب ملف الإخراج في نفس الدليل الذي يطابقه الـ glob، مكوّنًا حلقة تغذية مرتدة لا نهائية:
flowchart LR
A["bash: for f in tasks/*.output; tail -5 $f"] --> B["الكتابة إلى tasks/task-A.output"]
B --> C["الـ glob يطابق task-A.output نفسه"]
C --> D["tail -5 يقرأ الإخراج نفسه"]
D --> E["إضافة إلى نفسه"]
E --> Cأبلغ عدة مستخدمين عن نفس المشكلة بأحجام 1.2 تيرابايت، 460 جيجابايت، 303 جيجابايت، 235 جيجابايت، 480 جيجابايت، 36 جيجابايت. جمع المعلقون 70 قضية مفتوحة، مقسمة إلى 15 مجموعة؛ فقط المجموعتين الأوليين أبلغا عن استهلاك قرص يقترب من 9.5 تيرابايت. يمكن أن تصل سرعة الكتابة إلى 425 ميغابايت/ثانية، وتستمر 18 دقيقة حتى امتلاء القرص.
فشل متسلسل: انهيار لا يمكن عكسه بعد امتلاء القرص
يصف Issue #24207 سلسلة من الانهيارات الكارثية بعد امتلاء القرص:
flowchart TD
A["مساحة القرص = 0"] --> B["فشل كتابة .claude.json"]
B --> C["إنشاء ملف بطول صفر"]
C --> D["قراءة JSON غير صالح"]
D --> E["الكتابة فوق جميع إعدادات المشروع"]
E --> F["تلف رموز OAuth/API"]
F --> G["الحاجة إلى إعادة المصادقة"]
G --> H["إيقاف جميع الوكلاء/الجلسات النشطة"]
H --> I["عدم القدرة على الاسترداد حتى بعد تحرير مساحة القرص"]لا توجد تحذيرات، ولا تخفيض جودة تدريجي، ولا مسار استعادة. يجب على المستخدم إيقاف جميع العمليات يدويًا، تحرير المساحة يدويًا، وإعادة تكوين الإعدادات يدويًا.
كتابة متزامنة: لا قفل، لا معاملة، لا تنسيق
الملف القفل الوحيد في دليل ~/.claude/ هو .update.lock (5 بايت). جميع عمليات الكتابة الأخرى لا تحميها أي آلية قفل:
| الملف | الكاتب | آلية القفل | العواقب المعروفة |
|---|---|---|---|
sessions-index.json | كل جلسة في المشروع | لا شيء | حالة سباق |
{uuid}.jsonl | الجلسة الرئيسية + ضغط | لا شيء | فقدان مدخلات |
.claude.json | كل عملية | لا شيء | تلف الإعدادات (8 تقارير) |
file-history/* | كل تعديل/كتابة | لا شيء | نمو لا نهائي |
الوضع أسوأ على Windows: حلول الكتابة الذرية (الكتابة إلى .tmp ثم rename()) تفشل لأن rename() تُعيد EPERM عندما يكون الملف مقفولًا، مما يُدمّر الذرية تمامًا.
الذاكرة ووحدة المعالجة المركزية: من 13 جيجابايت RSS إلى نوبة نواة
استهلاك الذاكرة المتطرف على Windows
يسجل Issue #24840 حالة متطرفة على Windows: RSS 13.21 جيجابايت، واستهلاك الذاكرة الظاهرية 47.17 جيجابايت، بينما سعة الذاكرة الفعلية للجهاز 42.56 جيجابايت فقط. حدث 3.75 مليون خطأ صفحة، مما يدل على نشاط قرص مستمر. خلال 347 ثانية تشغيل، كان وقت CPU في وضع المستخدم 35 ثانية فقط، أي حوالي 90% من الوقت كان ينتظر I/O وswap. أدى ذلك إلى توقف تطبيقات أخرى مثل متصفح Opera عن الاستجابة.
نوبة نواة macOS
يُبلغ Issue #39253 عن عواقب أكثر خطورة: على MacBook Pro M3 Pro (18 جيجابايت RAM)، تشغيل عدة نسخ من Claude Code يسبب نوبات نواة macOS. تم ملاحظة نوعين من النوبات: قتل OOM بواسطة Jetsam (ضغط الذاكرة يقتل عملية watchdogd الحيوية) وtimeout للـ watchdog (watchdogd لم يُرسل إشارة خلال أكثر من 90 ثانية بسبب نقص الموارد). يعيد النظام تشغيل نفسه دون تحذير، ولا يظهر أي حوار خطأ، ولا يُحفظ أي عمل.
عملية يتيمة: تستمر بعد إغلاق الطرفية
يُبلغ Issue #44507 (أبريل 2026، قبل أيام) عن عيب أساسي في إدارة دورة الحياة: بعد إغلاق نافذة الطرفية، تظل عملية Claude Code حية. استهلكت عملية منفردة 35.4 جيجابايت RSS و95.5% من CPU خلال 21 يومًا. السبب هو عدم وجود معالج process.stdin.on("end") في نقطة الدخول الرئيسية، ووجود أكثر من 55 مؤقت setInterval (للتنقيب، التتبع، تحديث شريط الحالة) يبقي حلقة أحداث Node.js نشطة إلى ما لا نهاية. لا يُقيد كومة V8 نموها، ولا توجد ضغط GC خامل، ولا حد --max-old-space-size، ولا مراقب إغلاق ذاتي.
تجميد 100% CPU
يُبلغ Issue #27415 عن تجميد CPU بنسبة 100% نتيجة لتفعيل TaskStop، السبب هو حلقة غير منضبطة في posix_spawn داخل وقت تشغيل Bun. كما يُشير Issue #26224 إلى تجميد Claude Code لمدة 5-20 دقيقة عند معالجة طلبات ضخمة.
فشل نظامي في بنية الملفات المسطحة
تخصيص دون تنظيف: نمط بنية متكرر عبر جميع القضايا
أشار المجتمع، ممثلًا بـ kolkov، في عدة قضايا إلى أن السبب الجذري هو نفسه:
هذا التسرب في
.nodeليس مجرد خطأ معزول—إنه عرض لنمط بنية متكرر حيث يخصص Claude Code موارد دون تنظيفها.
من 2025 إلى 2026، تطورت المشكلة من تضخم ملف .claude.json إلى تضخم ملفات JSONL المتفرقة، لكن بنية التخزين المسطحة بقيت دون تغيير: لا أقفال، لا معاملات، لا تنظيف، لا ضغط.
SQLite والعملية الخدمية المحلية: بدائل المجتمع
اقترح المجتمع مرارًا استخدام SQLite بدلاً من ملفات مسطحة. قاعدة بيانات SQLite يمكنها حل جميع المشكلات: وضع WAL يوفّر قراءة متزامنة + كتابة ذرية، المعاملات تضمن كتابة كاملة أو لا شيء، ضغط مدمج، تنظيف TTL، إزالة تكرار المحتوى، وتوافقية عبر الأنظمة.
اقتُرح أيضًا إدخال عملية خدمية محلية (مشابهة خادم LSP أو بنية Docker)، حيث تتواصل جميع عمليات Claude Code عبر IPC لتنسيق دون تغيير طبقة التخزين.
مقارنة مع روبوت stale
صنّف المساهم gebeer الوضع بدقة:
شكرًا لتحليلك المفصل. كان يجب على الصيانة القيام بذلك منذ زمن طويل.
أضاف kolkov:
السخرية هي أن المجتمع يقوم بالتصحيح بدلاً منهم—تحليل الكود العكسي، تتبع مسارات الأخطاء، تقديم تصحيحات مع مقتطفات—ثم يرد الروبوت بـ “إغلاق بعد 60 يومًا”.
مقارنة إدارة الموارد مع أدوات مماثلة
GitHub Copilot يعمل كامتداد VS Code، ويخضع لحدود الذاكرة وإدارة دورة الحياة التي يفرضها المضيف. Cursor، وهو فرع من VS Code، يشارك نفس الإطار. كلاهما يستخدم SQLite أو قاعدة بيانات مشابهة، مما يدعم التزامن والمعاملات طبيعياً. اختار Claude Code عملية مستقلة + ملفات مسطحة، لكنه لم يُطبق إدارة موارد العملية المطلوبة—لا حد للذاكرة، لا حصة قرص، لا مراقب عملية، ولا إغلاق أنيق. سلوكه أقرب إلى نموذج نموذج أولي تجريبي وليس أداة جاهزة للإنتاج.
التناقض بين قدرة النموذج وجودة الهندسة
ملف حزمة بحجم 11.3 ميغابايت، 413 استدعاء نظام ملفات متزامن، 1087 غلاف CJS/ESM، لا تنظيف موارد، لا تحكم في التزامن، ولا مراقبة مساحة القرص—هذه ليست حالات طرفية، بل عيوب بنية نظامية. من أغسطس 2025 (Issue #5024) إلى أبريل 2026 (Issue #44507)، استمر المجتمع في الإبلاغ عن نفس الفئة من المشكلات، مقدمًا تحليلات مفصلة واقتراحات إصلاح، بينما تم وسم العديد من القضايا كـ “غير مخطط لها” أو إغلاقها آليًا بواسطة روبوت stale. أداة ترميز بالذكاء الاصطناعي ذات جودة شفرة تحتاج إلى تدقيق وإصلاح من المجتمع—هذا التناقض بحد ذاته يستحق التفكير.
إذا كنت تستخدم Claude Code، يُنصح بفحص حجم دليل ~/.claude بانتظام، وتنظيف ملفات .node المؤقتة، واستخدام Ctrl+C للخروج بشكل صحيح قبل إغلاق الطرفية. إذا اختفت مساحة القرص فجأة، الآن لديك فكرة عن مكان البحث عن السبب.