دليل المستخدم
حرّر هذه الصفحة على GitHubالمساعدة — career-ops-ui
دليل شامل لكل صفحة في التطبيق، من لحظة تشغيله حتى الحصول على مقابلة عمل. كل عنوان ## أدناه يقابل إدخالاً في الشريط الجانبي أو مرحلة من مراحل سير العمل. اقرأه من البداية إلى النهاية عند أول استخدام؛ وانتقل لاحقاً إلى أي قسم تريده عبر جدول المحتويات في الشريط الجانبي للمساعدة.
الجمهور المستهدف: كل من أضاف هذه الواجهة داخل نسخة
career-opsوشغّلbash bin/start.sh. لا يُفترض أي معرفة مسبقة بـ career-ops.
حول career-ops
career-ops نظام مفتوح المصدر للبحث عن عمل، يعمل عبر أوامر مائلة داخل أي واجهة سطر أوامر لبرمجة الذكاء الاصطناعي (Claude Code، Gemini CLI، Codex، Qwen Code، OpenCode، GitHub Copilot CLI — وأي واجهة متوافقة مع Claude تعمل بالطريقة ذاتها). النظام مستقل عن النموذج المستخدم. يقيّم كل إعلان وظيفي مقابل سيرتك الذاتية CV وفق معيار سداسي الأبعاد يتراوح بين 0.0 و5.0، ويُنشئ سيرًا ذاتية PDF مخصصة، ويتتبع كل طلب توظيف محلياً على جهازك.
المرجع الأساسي (اقرأها بهذا الترتيب عند التثبيت الأول):
- ما هو career-ops — النظام ومبادئه وقاموس مفاهيمه.
- مسح بوابات الوظائف — اكتشاف الوظائف الشاغرة وتعبئة الخط الوظيفي Pipeline.
- التقديم على وظيفة — سير تقديم كامل مع قراءة النماذج عبر Playwright.
- تقييم العروض دفعةً واحدة
— تقييم أكثر من 10 إعلانات دفعةً عبر
batch-runner.sh. - إعداد Playwright — تثبيت Chromium وتسجيل MCP لإنشاء PDF وملء النماذج.
المبادئ الأساسية (من career-ops.org/docs/introduction/what-is-career-ops):
- مفتوح المصدر فعلاً — MIT، بلا طبقة مدفوعة، بلا قوائم انتظار، بلا بيانات استخدام، بلا حسابات. يعمل النظام بدون اشتراكات أو حسابات أو تتبع. تخضع المساهمات البرمجية لمراجعة المجتمع قبل الإصدار.
- السيادة على البيانات —
cv.mdوconfig/profile.ymlوdata/وreports/وinterview-prep/لا تغادر جهازك إلا إذا دفعتها أنت. تشغّله محلياً مع احتفاظك الكامل بملكية بياناتك. - معمارية مستقلة عن الذكاء الاصطناعي — career-ops لا يحزّم أي نموذج. يعمل كأوامر داخل واجهات CLI للذكاء الاصطناعي الموجودة. بدّل المزودين (Anthropic ↔ Gemini ↔ OpenAI) وتاريخ تقييماتك يبقى متسقاً.
- التقديم بيد الإنسان — career-ops يُعدّ الإجابات ويفتح النموذج، لكن أنت من تنقر على إرسال. النظام لا يتقدم تلقائياً أبداً. يوفر النظام البنية والتقييم؛ الإنسان يحتفظ بصلاحية الإرسال النهائي.
- بحث منظّم — مُصمَّم لصيد وظائف نشط ومتعمّد مع طلبات تقديم متعددة؛ ليس أداة لطلب واحد، وليس محرك توصيات. الإعداد يستغرق نحو 15 دقيقة ويفترض ارتياحاً مع سطر الأوامر.
ما ليس career-ops (أهداف مستبعدة صراحةً):
- ليس أداة تقديم تلقائي. لن يُرسل النماذج بدلاً عنك.
- ليس أداة إعادة بناء سيرة ذاتية. يُخصّص لكل إعلان وظيفي؛ لا يخترع خبرات.
- ليس محسّناً لملف LinkedIn. ملفك شأنك.
- ليس بديلاً عن جدول بيانات مخفياً خلف واجهة SaaS. البيانات ملفات markdown عادية على نظام ملفاتك.
المفاهيم الأساسية (القاموس الكامل — كل ما يلمسه career-ops):
| المفهوم | ما هو |
|---|---|
| Mode | قالب prompt تحت modes/<slug>.md. المدمج: oferta، deep، apply، pipeline، batch، contacto، followup، interview-prep، patterns، project، training، ofertas، auto-pipeline، pdf، latex، scan، tracker. |
| Archetype | ملف دور مستهدف في config/profile.yml. توازن أوزان المعيار تطابقَ المهارات مع النمط المهني النشط — الحقل الأهم على الإطلاق. |
| Pipeline | data/pipeline.md — صندوق وارد يضم روابط إعلانات الوظائف بانتظار التقييم. |
| Tracker | data/applications.md — جدول GFM تاريخي لكل تقييم وحالة طلب توظيف. |
| Report | reports/<NNN>-<company>-<DATE>.md — تقييم A–F كامل لكل إعلان، مع الدرجة والمشروعية في الترويسة. |
| Scan history | data/scan-history.tsv — سجل إلحاقي؛ يمنع التكرار عبر عمليات المسح. |
| Proof points | كتل شواهد STAR+R مستخرجة من cv.md، تُعاد الاستفادة منها في التقييم وإجابات التقديم وإعداد المقابلات. |
| JD store | jds/jd-<date>-<ts>.txt — توصيفات الوظائف المحفوظة حرفياً أثناء التقييم لصون الأثر التدقيقي. |
| Interview-prep | interview-prep/<company>-<role>.md — ملخصات بحثية معمّقة وأوراق جولة أولى. |
| Batch additions | batch/tracker-additions/*.tsv — صفوف معلّقة في قائمة انتظار batch-runner.sh للدمج في المتتبع. |
career-ops مقابل career-ops-ui (هذا التطبيق)
| career-ops (CLI) | career-ops-ui (هذا التطبيق) | |
|---|---|---|
| أين يعمل | داخل Claude Code / Gemini CLI / Codex / Qwen Code / OpenCode / GitHub Copilot CLI | http://127.0.0.1:4317 في متصفحك |
| الواجهة | أوامر /career-ops <mode> مائلة |
شريط جانبي بصفحة لكل مرحلة |
| ملء النماذج | نعم، عبر Playwright MCP | لا — يُنشئ قائمة مراجعة وأنت تكملها في CLI |
generate-pdf.mjs |
📄 توليد PDF في #/cv و#/reports/:slug و#/evaluate و#/deep و#/interview-prep |
|
| ملفات البيانات | مشتركة مع career-ops-ui | مشتركة مع career-ops |
career-ops-ui إضافات خالصة. لا شيء داخل career-ops/ يتغير. كلتا الواجهتين تتشاركان cv.md وconfig/profile.yml وportals.yml وdata/ وreports/ وinterview-prep/ وmodes/.
عتبات الإجراء حسب الدرجة
بمجرد تقييم إعلان وظيفي، تحدد الدرجة ما يُفعل لاحقاً (الجدول الأساسي من career-ops.org/docs/introduction/what-is-career-ops):
| الدرجة | الخطوة التالية |
|---|---|
| ≥ 4.5 | شغّل /career-ops apply — توافق عالٍ، تقدّم فوراً. |
| 4.0 – 4.4 | تقدّم، أو /career-ops contacto للحصول على توصية دافئة أولاً. |
| 3.5 – 3.9 | شغّل /career-ops deep — ابحث عن الشركة والدور قبل القرار. |
| < 3.5 | تجاهل إلا إذا كان لديك سبب شخصي محدد. |
يُبرز #/dashboard و#/tracker في career-ops-ui كل صف يبلغ 4.0 فأكثر لتختار الإجراء دون إعادة تشغيل أي شيء.
الوثائق الخارجية
المرجع الكامل لمحرك career-ops الأساسي (المسح والمعيار التقييمي والمعالجة الدفعية وسير التقديم وإعداد Playwright) موجود في career-ops.org/docs:
1. البداية السريعة — دليل خطوة بخطوة من “إنشاء السيرة الذاتية” حتى “التقديم والتواصل”
هذا هو الدليل الرسمي زراً بزر. اتبعه بالترتيب في المرة الأولى. كل خطوة تذكر المسار الدقيق والزر الدقيق وما ستراه عند النجاح. الأقسام 2–16 أدناه تتعمق في كل مرحلة.
اسأل الدليل. افتح اسأل الدليل 💬 (الشريط الجانبي، تحت المساعدة) واكتب سؤالاً — يجيب فقط من هذا الدليل بلغتك ولا يقرأ سيرتك الذاتية أبداً. المساعد نفسه على بُعد نقرة من كل صفحة — يطفو زر دردشة على شكل روبوت في الزاوية السفلية اليمنى (السفلية اليسرى في اللغات من اليمين إلى اليسار)؛ انقر لتسأل دون مغادرة ما تفعله.
تشغيل وإعداد بأمر واحد. من سطر الأوامر يمكنك إتمام الإعداد الكامل دون لمس الواجهة:
career-ops-ui setup # تثبيت التبعيات → فحص صحة النظام → تشغيل الخادم career-ops-ui init # اختيار مزود LLM ولصق مفتاحه (الإدخال محجوب) career-ops-ui doctor # إعادة التحقق في أي وقت (الخروج 0 ⇔ كل ما هو مطلوب أخضر) career-ops-ui run # تشغيل الخادم فحسب على http://127.0.0.1:4317 career-ops-ui open # فتح لوحة التحكم ورفعها في المتصفحبعد
setup/runيُفتح تبويب المتصفح ويُحضر إلى الواجهة تلقائياً (v1.43.0)؛career-ops-ui openيفعل الشيء ذاته عند الطلب.NO_OPEN=1يعطّل الفتح التلقائي في بيئات headless/CI.
setupينفّذ السلسلة كاملة بنفسه.initيكتب المفتاح إلىcareer-ops/.envفي المشروع الأب عبر المسار المتحقق منه ذاته الذي تستخدمه تبويبة مفاتيح API في#/config، ويضبطLLM_PROVIDER(auto|claude|gemini) الذي تستعمله مسارات التقييم المباشر والبحث العميق والوضع والخط الآلي. صيغة CI:career-ops-ui init --provider claude --anthropic-key sk-ant-… --yes. تفضّل الواجهة؟ تابع الخطوات أدناه.
أ. الإعداد (مرة واحدة، ~5 دقائق)
يجب أن يكون career-ops-ui في career-ops/web-ui/ (متداخلاً داخل مشروع career-ops الأب). يقرأ cv.md وconfig/ وdata/ من المجلد الأب عبر ../ ولا يعمل بشكل مستقل. إذا لم يُعثر على career-ops-ui init بعد سحب، شغّل cd career-ops/web-ui && npm install && npx career-ops-ui init.
الخطوة 1 — افتح التطبيق على http://127.0.0.1:4317. إن لم يكن يعمل، شغّل في سطر الأوامر bash bin/start.sh من جذر المستودع. تُحمَّل لوحة التحكم (#/dashboard).
الخطوة 2 — انقر ❤ الصحة في الشريط الجانبي الأيسر. كل فحص مطلوب يجب أن يكون أخضر:
cv.mdوconfig/profile.ymlوportals.ymlموجودة- مفتاح API مضبوط (على الأقل أحد
ANTHROPIC_API_KEY/GEMINI_API_KEY) - Playwright مثبّت (مطلوب فقط إذا ستستخدم توليد PDF)
إن كان أي شيء أحمر، تُخبرك الصفحة بالملف أو متغير البيئة الذي يحتاج إصلاحاً. لا تتابع حتى تصبح الصحة خضراء.
الخطوة 3 — انقر ⚒ إعدادات التطبيق في الشريط الجانبي. ستصل إلى تبويبة مفاتيح API والبيئة التشغيلية.
- الصق
ANTHROPIC_API_KEY(مفضّل — تسجيل هيكلي أفضل لفترات طويلة) و/أوGEMINI_API_KEY. احصل على المفاتيح من https://console.anthropic.com/settings/keys أو https://aistudio.google.com/apikey. - انقر 💾 حفظ. ثم انقر ▶ اختبار Anthropic (أو Gemini) — رحلة صغيرة ذهاباً وإياباً تؤكد أن المفتاح يعمل.
الخطوة 4 — انتقل إلى تبويبة الملف الشخصي في الصفحة ذاتها. هذا هو محرر YAML المباشر لـ config/profile.yml. حرّر على الأقل:
candidate.full_name— استبدل أي عنصر تعبئة (“Jane Smith”) باسمك الحقيقيcandidate.emailوlinkedinوgithub— تُستخدم في خطابات التغطيةtarget.roles— المسميات الوظيفية التي ستتقدم إليهاtarget.comp_total_min_usd— الحد الأدنى للتعويض الإجمالي؛ العروض دون هذا الرقم تُعلَّم في قسم D من كل تقييمtarget.archetypes— الأنماط المهنية التي تقبلها (الحقل الأهم على الإطلاق)
انقر 💾 حفظ. يتحقق الخادم من YAML ويضع ترويسة # Career-Ops Profile Configuration المعيارية تلقائياً.
ب. السيرة الذاتية CV (مرة واحدة، ~10 دقائق)
الخطوة 5 — انقر ✎ السيرة الذاتية في الشريط الجانبي. عمودان: المحرر على اليسار، والمعاينة الحية على اليمين.
الخطوة 6 — اختر مساراً لملء المحرر:
- تحميل سيرة ذاتية موجودة — انقر 📁 تحميل السيرة الذاتية، اختر أياً من
.docx / .doc / .odt / .rtf / .pdf / .html / .txt / .md. يحوّل الخادم إلى markdown عبر pandoc أو pdftotext، ويُزيل XSS، ويضع النتيجة في المحرر. راجع التحويل — ملفات PDF خاصةً قد تفقد دقة التخطيط. - لصق markdown مباشرةً — مساحة النص هي محرر markdown؛ اللوحة اليمنى هي ما سيراه النموذج (وأصحاب العمل مستقبلاً).
- نصائح الأسلوب: نقطة واحدة = إنجاز واحد بمقياس. حافظ على أقل من 1500 كلمة. الأقسام بهذا الترتيب: ملخص، خبرة، مشاريع، تعليم، مهارات.
الخطوة 7 — انقر 💾 حفظ (أعلى يمين صفحة السيرة الذاتية). يُطهّر الخادم (<script> / javascript: / المعالجات المضمّنة تُحذف) ويكتب cv.md. إشعار: “تم الحفظ”.
الخطوة 8 (اختياري) — انقر 📄 توليد PDF. يشغّل generate-pdf.mjs في المشروع الأب (يتطلب Playwright) ويُنزَّل PDF الجديد تلقائياً إلى متصفحك عند الانتهاء. القائمة في أسفل الصفحة تحتفظ بكل ملف تم توليده سابقاً.
ج. اكتشاف الوظائف (دقيقتان تقريباً لكل مسح)
الخطوة 9 — انقر 🌐 مسح في الشريط الجانبي. تأكد أن portals.yml يسرد البوابات التي تهمك (القسم 5 من هذه المساعدة). اضغط زر 🌐 مسح الآن. يبثّ سجل SSE مباشر بينما يجوب الماسح Greenhouse / Ashby / Lever / Workable / SmartRecruiters / Workday (البوابات الإنجليزية) وhh.ru / Habr Career (البوابات الروسية إن فُعّلت).
الخطوة 10 — عند انتهاء المسح، راجع النتائج. انقر أي علامة شركة للتصفية؛ انقر أيقونة ↗ لفتح صفحة وظائف الشركة في تبويب جديد. كل وظيفة شاغرة تجاوزت مرشح العنوان تُضاف إلى الخط الوظيفي.
د. تقييم العروض (30 ثانية تقريباً لكل إعلان)
الخطوة 11 — انقر الخط الوظيفي في الشريط الجانبي. ترى كل رابط قائم الماسح. انقر أي إدخال لمعاينة الإعلان مضمّناً.
الخطوة 12 — انقر ▶ تقييم بجانب أي إعلان. ينتقل هذا إلى #/evaluate. مع مفتاح API مضبوط يعمل مباشرةً؛ بدونه تحصل على prompt يدوي للصقه في نموذجك اللغوي الخاص. الوضع المباشر يُنتج درجة 0–5 مقابل سيرتك الذاتية عبر الأقسام A–G (الدور / الشركة / التعويض / المخاطرة / التمدد / الانسجام الثقافي / الحكم). يُحفظ في reports/<date>-<slug>.md.
الخطوة 13 — انقر التقارير في الشريط الجانبي وراجع أحدث تقييم. كل ما هو أدنى من comp_total_min_usd يُعلَّم باللون الأحمر في القسم D. كل ما يحمل Verdict: pursue هو قائمتك المختصرة.
هـ. القرار والبحث المعمّق عن الشركة (~3 دقائق)
الخطوة 14 — اختر وظيفة تستحق المتابعة. انقر البحث العميق في الشريط الجانبي. أدخل اسم الشركة والدور. يُنتج النموذج ملخصاً مؤسسياً من 7 أقسام (المهمة، الأخبار الأخيرة، التقنيات المستخدمة، إشارات التوظيف، معايير التعويض، المخاطر، الزاوية الموصى بها). يُحفظ في interview-prep/<company>-<role>.md.
و. التقديم (~5 دقائق لكل طلب)
الخطوة 15 — انقر قائمة مراجعة التقديم في الشريط الجانبي. الصق رابط الوظيفة والإعلان. يُنشئ المساعد قائمة مراجعة تقديم خطوة بخطوة:
- مسوّدة خطاب تغطية مخصصة (تستخدم
cv.mdوprofile.yml) - كلمات مفتاحية محددة لمرآة الإعلان
- الملفات المرفقة (PDF السيرة الذاتية — انظر الخطوة 8)
- أين تتقدم (رابط صفحة الوظائف الرسمي، ليس تحويلات المجمّعات)
- تذكير: لا تقدّم أبداً تلقائياً — المراجعة النهائية والتقديم يدويان دائماً.
الخطوة 16 — افتح صفحة الوظائف في تبويب جديد. استخدم قائمة مراجعة التقديم كقائمة مهامك. قدّم عبر نموذج الشركة الفعلي. أرفق PDF الذي أنشأته في الخطوة 8.
الخطوة 17 — تواصل مع إنسان حقيقي. افتح وضع التواصل الخارجي (#/contacto في الشريط الجانبي). يُصيغ النموذج رسالة LinkedIn / بريد إلكتروني قصيرة مخصصة للملخص المؤسسي من الخطوة 14. خصّص الافتتاحية (تفصيل محدد من ملخص بحثك المعمّق). أرسلها.
ز. التتبع والمتابعة (مستمر)
الخطوة 18 — انقر المتتبع في الشريط الجانبي وأضف صفاً للطلب: الشركة، الدور، الدرجة، الحالة Applied، رابط التقرير، رابط ملخص البحث المعمّق. التاريخ يُملأ تلقائياً.
الخطوة 19 — بعد أسبوع: افتح وضع المتابعة (#/followup). يُصيغ بريداً إلكترونياً مهذباً يستذكر الطلب الأصلي. أرسله. حدّث حالة المتتبع إلى Followed up.
الخطوة 20 — عند تلقي دعوة مقابلة، شغّل وضع إعداد المقابلة (#/interview-prep). يُولّد تحضيراً مستهدفاً للشركة والمرحلة المحددة (تصميم الأنظمة / السلوكيات / البرمجة). يسحب من ملخص البحث المعمّق تلقائياً.
الخطوة 21 — تلقيت العرض؟ حدّث حالة المتتبع إلى Offer وارجع إلى قسم التعويض في تقرير تقييمك — رقم الحد الأدنى للقبول موجود هناك.
ملخص — ترتيب الشريط الجانبي يتطابق مع سير العمل
الصحة → إعدادات التطبيق → الملف الشخصي → السيرة الذاتية → مسح → الخط الوظيفي → تقييم → تقارير → بحث معمّق → قائمة مراجعة التقديم → تواصل خارجي → متتبع → متابعة → إعداد مقابلة → سجل النشاط
هذا كل شيء. 21 خطوة، زراً بزر، من الصفر حتى العرض.
الخط الآلي بنقرة واحدة (#/auto) — اختصار الـ 21 خطوة
إذا أردت تقييم إعلان محدد بسرعة، تجاهل الجولة اليدوية. الشريط الجانبي → ✨ الخط الآلي (أو زر ✨ في لوحة التحكم) يفتح شاشة مخصصة: الصق رابط الوظيفة، اضغط Enter أو انقر ▶ تشغيل الخط الكامل، ويُشغّل الخادم السلسلة كاملة في تمريرة واحدة قابلة للمراقبة:
- التحقق من الرابط — فحص آمن من SSRF (
isValidJobUrl)؛ يرفض loopback /file:/ IPs الخاصة / الأحرف البرمجية. - جلب توصيف الوظيفة —
safeGet(مثبّت DNS، يُعيد التحقق من التحويلات) يسحب الإعلان ويُطهّره. - التقييم مقابل سيرتك الذاتية — Anthropic (مفضّل) → Gemini احتياطياً → prompt يدوي إن لم يكن ثمة مفتاح.
- حفظ التقرير — يكتب
reports/<slug>.mdمع الدرجة والمشروعية في الترويسة. - الإضافة إلى المتتبع — يُلحق صفاً في
data/applications.md.
التغذية الراجعة المباشرة عبارة عن خطوات رأسية (كل خطوة تضيء: قيد التشغيل → انتهى / فشل). هي قائمة مرتبة مع aria-current على الخطوة النشطة ومنطقة مباشرة لقارئ الشاشة تُعلن كل انتقال. عند النجاح يرتبط بطاقة النتيجة مباشرةً بالتقرير المحفوظ (عرض التقرير · N/5) والمتتبع. تُعلَّم خطوة الفشل باللون الأحمر مع رسالتها ويُعاد تفعيل الزر لتصحيح الرابط وإعادة المحاولة دون إعادة تحميل.
لا مفتاح API؟ يعمل الخط في الوضع اليدوي: تنطوي الخطوات 3–5 وتحصل على بطاقة prompt جاهزة للنسخ (الصقها في Claude Code / Anthropic / Gemini). لا استدعاء مباشر للنموذج اللغوي، ولا إنفاق.
#/auto قابل للربط: #/auto?url=<encoded>&go=1 يفتح الشاشة ويبدأ تلقائياً. زر ✨ في لوحة التحكم وهذا الإدخال في الشريط الجانبي كلاهما يصلان هنا (تدفق واحد متسق — النافذة العابرة قبل v1.34 أُسّست لتصبح هذه الصفحة).
CLI (v1.38.0). أمر واحد ينفّذ السلسلة:
career-ops-ui setup(تهيئة → تثبيت → تشغيل). أوامر مستقلة:career-ops-ui doctor(فحص البيئة والمفاتيح والأدوات — نفس محرك صفحة الصحة؛ الخروج 1 عند أي فشل مطلوب)،career-ops-ui run،career-ops-ui init(معالج المزود والمفتاح، v1.39.0). المزودون (v1.39.0). تبويبة مفاتيح API تضيفLLM_PROVIDER(auto= Anthropic→Gemini الافتراضي ·claude·gemini) وحقلOPENAI_API_KEY(جهة CLI لـ Codex/OpenCode).career-ops-ui initمعالج تفاعلي للشيء ذاته.المزودون (v1.57.0). التقييم المباشر الآن بلا رأس يمتد عبر Anthropic → Gemini → OpenAI → Qwen → OpenRouter (ترتيب
auto؛LLM_PROVIDERيثبّت واحداً). OpenRouter — مفتاحOPENROUTER_API_KEYواحد يوفر 300+ نموذج؛ القائمة المنسدلةOPENROUTER_MODELتحمّل الكتالوج الحي من OpenRouter (بروكسي من جهة الخادم، مع احتياطي نظير مُنقّح دون اتصال). كذلك تم الإصلاح: المفاتيح الملصوقة بمسافة لاحقة / محيطة تُقلَّص الآن قبل التحقق، فلن تعود/#/configتُظهر “فشل التحقق” لأي مزود.
2. إعدادات التطبيق ومفاتيح API (#/config)
جديد في v1.55 → v1.56. عند غياب أي مفتاح LLM، يظهر شريط أحمر على كل شاشة يوضح أن ⚡ التشغيل المباشر في وضع الـ prompt اليدوي ويُحيل إلى هنا؛ بمجرد ضبط مفتاح يتحول إلى شريحة هادئة تُسمّي المزود النشط. قبل أي زر ⚡ تشغيل مباشر (
#/autoو#/evaluateو#/deepوالأوضاع) يظهر تقدير صريح للتكلفة (مثلاً “التكلفة المقدّرة: OpenAI gpt-5-codex · ~$0.04/تقييم”، أو ملاحظة بلا تكلفة API في الوضع اليدوي).#/scanيخفي المرشحات الثانوية خلف إفصاح مرشحات متقدمة؛#/trackerيضيف شرائح قمع قابلة للنقر + ترقيم اختياري من جهة الخادم؛#/pipelineيُظهر صفوف افتراضية تتجاوز 1000.
أدوات CLI للذكاء الاصطناعي. يعرض تبويب أدوات CLI للذكاء الاصطناعي أيّ CLI وكيلية (Claude Code وCodex وGemini وOpenCode وCopilot وQwen وAntigravity) مثبَّتة على الخادم — فحص للـPATH للقراءة فقط دون تشغيلها. المظهر → إظهار شعارات الشركات (معطّل افتراضياً) يعرض أيقونة كل شركة في جدول الفحص، مجلوبة من نطاقها الخاص (لا خدمة خارجية).
ثلاث تبويبات:
- مفاتيح API والبيئة التشغيلية — نموذج حقول منظّم فوق
.envللمشروع الأب (الملف ذاته الذي تقرأه سكريبتات Node لـ career-ops عند بدء التشغيل). مجمَّع: مفاتيح API / البيئة التشغيلية / المصادر الإقليمية. التبويبة تكشف أيضاً محدّدات النموذج لكل مزود —OPENAI_MODEL(OpenAI/Codex) إلى جانبANTHROPIC_MODELوGEMINI_MODEL. - الملف الشخصي — نموذج حقل بحقل فوق
config/profile.yml(web-ui 1.32.0). الحفظ يدمج في الملف — أنماطك المهنية ونقاط الإثبات وأي مفاتيح مخصصة تُحفظ دون تغيير. - الأوضاع — نموذج حقول منظّم لـ
modes/_profile.md(web-ui 1.54.3)، مشتق من المخطط الموثّق. الأقسام من نوع القائمة — الأدوار المستهدفة / الإطار التكيّفي / أهداف التعويض — تُعرض كحقول سطر متكررة قابلة للإضافة والحذف؛ الأقسام النثرية — سرد الخروج / سياسة الموقع — تُعرض كمناطق نص مُسمّاة؛ أي قسم غير معروف أو غير قائمة يعود إلى منطقة نص حرفية مُسمّاة. الحفظ لا يزال يدمج حسب القسم — المقدمة والأقسام غير المعدّلة وأي أقسام مخصصة تُحفظ بايتاً بايت. يبقى إفصاح متقدم: markdown خام للتعديلات على الملف كاملاً — إضافة أقسام أو إزالتها أو تعديل المقدمة.
أي حفظ في تبويبة يُطبَّق فوراً — لا إعادة تشغيل للخادم.
إعداد مزود LLM خطوة بخطوة. التقييم المباشر ⚡ في الواجهة يعمل بلا رأس ويستخدم مفتاح API واحداً. يعمل بمنطق “أو” — اضبط أياً منها ويعمل مباشرةً؛ مع عدة مفاتيح مضبوطة، يُفضّل auto بهذا الترتيب: Anthropic → Gemini → OpenAI → Qwen. (career-ops نفسه مستقل عن CLI — يمكنك أيضاً تشغيله داخل Claude Code وCodex وGemini وOpenCode وQwen وCopilot وKimi؛ هذا منفصل عن مفتاح headless هذا.)
- افتح
#/config→ تبويبة مفاتيح API والبيئة التشغيلية. - اختر مزودك في
LLM_PROVIDER:auto(يستخدم أي مفتاح مضبوط)، أو أجبر واحداً بـclaude/gemini/openai/qwen. - أدخل المفتاح والنموذج للمزود الذي اخترته:
- Anthropic — اضبط
ANTHROPIC_API_KEY(console.anthropic.com)، اختيارياًANTHROPIC_MODEL(الافتراضيclaude-sonnet-4-6). - Gemini — اضبط
GEMINI_API_KEY(aistudio.google.com/apikey)، اختيارياًGEMINI_MODEL(الافتراضيgemini-2.0-flash). - OpenAI — اضبط
OPENAI_API_KEY(platform.openai.com)، اختيارياًOPENAI_MODEL(الافتراضيgpt-5-codex). - Qwen — اضبط
QWEN_API_KEY(Alibaba Model Studio / DashScope، dashscope.console.aliyun.com)، اختيارياًQWEN_MODEL(الافتراضيqwen-max). لنقطة النهاية الصينية اضبطQWEN_BASE_URLفي.envالخام.
- Anthropic — اضبط
- انقر حفظ. تُكتب المفاتيح إلى
.envللمشروع الأب؛ التغيير يسري فوراً — لا إعادة تشغيل للخادم. - تحقق في
#/evaluate: الصق رابط وظيفة / توصيفها واضغط ⚡ تشغيل مباشر. ترويسة النتيجة تُظهر المزود الذي عمل (anthropic/gemini/openai/qwen). إن لم يكن ثمة مفتاح → تحصل على prompt النسخ واللصق اليدوي.
الأسرار تُخفى بعد الحفظ ولا تُسجَّل أبداً. حقول معرّف النموذج (*_MODEL) ليست سرية.
تبويبة الملف الشخصي (نموذج الحقول — v1.32.0)
قبل v1.32.0 كانت هذه التبويبة منطقة نص YAML خام واحدة حيث تعيش كل الإعدادات في كتلة غير مُميَّزة. هي الآن نموذج منظّم، حقول مجمَّعة في ثلاثة أقسام قابلة للطيّ:
- المرشّح — الاسم الكامل (مطلوب)، البريد الإلكتروني، الهاتف، الموقع، LinkedIn، GitHub، رابط المحفظة، X / Twitter.
- السرد — العنوان، قصة الخروج.
- التعويض — النطاق المستهدف، العملة، الحد الأدنى للانسحاب، المرونة الجغرافية.
- محررات المصفوفات المنظّمة (web-ui 1.35.0) — محررات إضافة/حذف صفوف للحقول ذات الشكل القائمي، بحيث لا تحتاج إلى YAML خام حتى لها: الأدوار المستهدفة + نقاط القوة (قوائم نصية)؛ الأنماط المهنية (اسم / مستوى / صفوف ملاءمة)؛ نقاط الإثبات (اسم / رابط / صفوف مقياس بطولي). الصفوف الفارغة تُسقط؛ القائمة المُفرَغة تحذف المفتاح نظيفاً. الضمان ذاته بالدمج لا الاستبدال — كل مصفوفة لا تلمسها تبقى سليمة.
كيف الحفظ آمن:
- يرسل النموذج فقط 14 مساراً عددياً مُصمَّماً بالشكل
{ fields: { "candidate.full_name": … } }. يقرأ الخادمconfig/profile.ymlالموجود، يضبط/يمسح تلك الأوراق فحسب، ويُعيد تسلسل الكائن كاملاً — لذا المصفوفات المتداخلة التي لا يُصمّمها النموذج (target_roles.archetypesوnarrative.proof_pointsوnarrative.superpowers) وأي مفاتيح مخصصة أضفتها يدوياً تنجو من الرحلة ذهاباً وإياباً سليمةً. مسح حقل يحذف المفتاح نظيفاً (لا بقاياphone: ""). - التحقق لا يزال يشترط الاسم الكامل؛ ترويسة
# Career-Ops Profile Configurationتُختم تلقائياً. - مفاضلة واحدة: حفظ نموذج الحقل يُعيد تسلسل YAML، فتُفقد تعليقات
#المضمّنة. لحفظ التعليقات أو تعديل المصفوفات المتداخلة، استخدم إفصاح متقدم: تعديل YAML الخام في أسفل التبويبة — هو محرر الملف الكامل قبل v1.32، دون تغيير (يستبدل الملف كاملاً عند الحفظ). - الملخص القراءة-فقط في
#/profileهو الرفيق البصري.
المفاتيح المعروفة
| المفتاح | ما يفعله | أين تحصل عليه |
|---|---|---|
ANTHROPIC_API_KEY |
يُفعّل استدعاءات Anthropic SDK المباشرة. مفضّل عند ضبط كلٍّ من Anthropic وGemini — مخرج منظّم أطول للتسجيل وتقييم الإعلانات والبحث المعمّق. | https://console.anthropic.com/settings/keys |
ANTHROPIC_MODEL |
تجاوز الافتراضي claude-sonnet-4-6. جرّب claude-opus-4-7 للاستدلال الأعمق، claude-haiku-4-5-20251001 لأسرع وأرخص. |
— |
GEMINI_API_KEY |
احتياطي عند غياب مفتاح Anthropic. يستخدمه gemini-eval.mjs لوضع oferta. الطبقة المجانية تكفي للحجم المنخفض. |
https://aistudio.google.com/apikey |
GEMINI_MODEL |
تجاوز نموذج Gemini الافتراضي. | — |
(الخادم يستخدم UA الافتراضي) |
مطلوب عند تشغيل مسح hh.ru من خارج روسيا (الـ API يعيد 403 مع User-Agents العادية). سجّل تطبيقاً في https://dev.hh.ru/admin واستخدم سلسلة UA الخاصة به. | dev.hh.ru |
PORT |
منفذ ربط Express. الافتراضي 4317. | — |
HOST |
عنوان الربط. الافتراضي 127.0.0.1. ضبط 0.0.0.0 يكشف الواجهة على الشبكة المحلية — لا بوابة مصادقة بعد، انظر وثيقة الاستعداد للإنتاج. |
— |
السلوك
- القراءة (
GET /api/config) تُعيد كل مفتاح معروف. المفاتيح السرية (ANTHROPIC_API_KEYوGEMINI_API_KEY) مُقنَّعة — ترىsk-ant•••••••a1b2، لا القيمة الكاملة أبداً. - الحفظ (
POST /api/config) يتحقق من كل قيمة، يكتب في<parent>/.env، ويُطبَّق فوراً على العملية الجارية. لا إعادة تشغيل مطلوبة. - القيمة الفارغة تحذف المفتاح. مفيد إذا أردت إلغاء استخدام IP/VPN روسي.
أزرار اختبار الدخان
بعد الحفظ، انقر ▶ اختبار Anthropic أو ▶ اختبار Gemini — كلاهما يُطلق prompt صغيراً (≤256 رمزاً في الناتج) فتنفق عملياً لا شيء بينما تتأكد من توصيل المفتاح. يعيد نموذجاً من ~200 حرف عند النجاح.
3. الملف الشخصي (#/profile — يمكن الوصول أيضاً عبر #/settings)
بطاقة ملخص قراءة فقط لـ config/profile.yml. للتعديل، اذهب إلى إعدادات التطبيق → تبويبة الملف الشخصي (#/config → الملف الشخصي) — منذ web-ui 1.32.0 هو نموذج حقل بحقل (المرشح / السرد / التعويض)، ليس كتلة YAML خام. الحفظ يدمج في الملف ذاته؛ هذه الصفحة تُعيد التحليل عند إعادة التحميل.
الحقول الأكثر أهمية:
candidate.full_name— يُستخدم في كل prompt. استبدل القالبJane Smithقبل مسح أي شيء حقيقي، وإلا ستصدر خطابات التغطية المُولَّدة باسم العنصر الوهمي.candidate.emailوlinkedinوgithub— مرجوع إليها في توليد خطاب التغطية وقائمة مراجعة التقديم.target.roles— المسميات الوظيفية المقبولة. المرشّح الإيجابي للماسح يستخدم هذا ضمنياً (عبرportals.yml::title_filter).target.comp_total_min_usd— الحد الأدنى للتعويض الإجمالي. يُعلّم القسم D في كل تقييم العروض الأدنى من هذا.target.archetypes— الحقل الأهم. هذه هي الأنماط المهنية التي تقبلها (مثلاًTech-Lead-BackendوFounding-EngineerوData-Platform). يُقابَل كل إعلان مع هذه الأنماط وأفضل نمط ملائم يظهر في ترويسة التقرير.
صفحة الصحة تعرض فحص الملف الشخصي مُخصَّص يفشل طالما يتطابق full_name مع اسم عنصر وهمي معروف.
4. السيرة الذاتية CV (#/cv)
المصدر الوحيد للحقيقة لكل تقييم وبحث معمّق وخطاب تغطية. موجودة في cv.md في جذر المشروع الأب.
خيارات التعديل
- لصقها مباشرةً — مساحة النص على اليسار محرر markdown. اللوحة اليمنى تعكس ما سيراه النموذج (وأصحاب العمل مستقبلاً).
- 📁 تحميل السيرة الذاتية — اختر ملفاً محلياً بأي من هذه التنسيقات ويُحوّله الخادم إلى markdown لك:
- التنسيقات النصية —
.mdو.markdownو.txtو.htmlو.htmتمر كما هي (HTML تمر عبر pandoc → GFM markdown). - تنسيقات Office —
.docxو.docو.odtو.rtfتُحوَّل عبر pandoc (brew install pandocعلى macOS،apt install pandocعلى Linux). - PDF —
.pdfيُستخرج عبر pdftotext من Poppler (brew install poppler/apt install poppler-utils). - يُوضع markdown المُحوَّل في المحرر؛ انقر 💾 حفظ للإبقاء. النتيجة مُطهَّرة (التعقيم ذاته من XSS كاللصق).
- الحد الأقصى: 10 ميغابايت لكل تحميل. الأكبر → 413.
- التنسيقات النصية —
- من LinkedIn — الطريق الأسهل: افتح Claude Code في المشروع الأب، شغّل
/career-ops، الصق رابط LinkedIn الخاص بك واطلبextract my CV from this and write it to cv.md.
ما يُطهَّر
من جهة الخادم، كل PUT إلى /api/cv يمرّ عبر stripDangerousMarkdown:
- علامات
<script>و<iframe>و<object>و<embed>و<svg>و<style>و<form>— تُحذف كلياً. - معالجات الأحداث المضمّنة (
onclick=وonerror=وما شابه) — تُجرَّد. - مخططات URI لـ
javascript:وvbscript:وdata:text/html— تُعطَّل.
يتضمن الرد sanitized: true كلما حُذف أي مما سبق، حتى تعلم إن كان المصدر يحتوي شيئاً مثيراً للقلق.
الحد الأقصى لحجم الجسم: 1 ميغابايت. أي شيء أكبر يعيد 413.
الأزرار الأخرى
- فحص التزامن — يشغّل
cv-sync-check.mjsفي المشروع الأب. يُعلّم التناقضات: مشروع مدرج في سيرتك لكن غير موجود في أنماطdata/applications.md، وما شابه. - 📄 توليد PDF — يُبث
generate-pdf.mjs. الناتج يُودَع فيoutput/*.pdf. يتطلب Playwright (صفحة الصحة تُظهر ما إذا كان مثبتاً فيnode_modulesللمشروع الأب). عند انتهاء التوليد، يُنزَّل أحدث PDF تلقائياً إلى مجلد التنزيلات الافتراضي لديك؛ القائمة على الصفحة تحتفظ بكل ملف تم توليده سابقاً.
نصائح الأسلوب والتنسيق
- نقطة واحدة = إنجاز واحد بمقياس. “قلّصت تأخر p99 بنسبة 38%” تتفوق على “حسّنت الأداء” في كل معيار تقييم.
- الأقسام بهذا الترتيب: الملخص (3–5 أسطر)، الخبرة (ترتيب زمني عكسي)، المشاريع (5 كحد أقصى)، التعليم، المهارات (بلا تكرار، بلا حشو مصطلحات).
- حافظ على أقل من 1500 كلمة. يستخدم معيار التقييم المعلومات الكثيفة؛ سيرة ذاتية ضخمة تُعاقَب بسبب الضجيج.
5. البوابات والمصادر (portals.yml)
يقع ملف تهيئة الماسح في portals.yml في جذر المشروع الأب. ثلاثة أقسام تهمّ. الأقسام الثلاثة في SPA (أدناه) تطابق مخطط career-ops.org الأساسي من scan-job-portals حرفياً.
اختصار: رابط
#/portalsيُحوَّل الآن مباشرةً إلى إعدادات التطبيق و(عند تهيئة مصدر إقليمي) ينتقل إلى مجموعة المصادر الإقليمية — فرابط#/portalsالمحفوظ أو المكتوب لم يعد يُعطي خطأ 404 (v1.42.0).
title_filter
title_filter:
positive: [backend, engineer, senior, tech lead, golang, php]
negative: [junior, intern, frontend, ios, android, java]
seniority_boost: [Senior, Staff, Lead, Principal]
تجتاز الوظيفة الممسوحة عند احتواء عنوانها على كلمة مفتاحية إيجابية واحدة على الأقل وعدم احتوائه على أي كلمة سلبية. نظّم كليهما. الكلمات المفتاحية مطابقات جزئية غير حساسة لحالة الأحرف.
seniority_boost هو المفتاح الثالث لمرشح العنوان. الكلمات المفتاحية المدرجة هنا لا تُصفّي شيئاً — بل ترفع الوظائف المطابقة أعلى في النتائج لكي تظهر “مهندس خلفية أول” قبل “مهندس”. الافتراضي: ["Senior", "Staff", "Lead"]. خصّصه ليتطابق مع كيفية تسمية أدوارك المستهدفة.
ابدأ بـ 3–5 كلمات مفتاحية إيجابية للوضوح؛ وسّع لاحقاً.
location_filter (اختياري — web-ui 1.33.0، الأب #570)
location_filter:
allow:
- "Remote"
- "United States"
- "Atlanta"
block:
- "India"
- "London"
- "Germany"
يُصفّي الوظائف الممسوحة بناءً على سلسلة الموقع (مطابقة جزئية غير حساسة لحالة الأحرف)، مطبَّق من كلٍّ من المسح الـ ATS والمسح الإقليمي. الدلالة مطابقة للـ scan.mjs الأساسي لـ career-ops:
- لا مفتاح
location_filter→ كل موقع يجتاز (الافتراضي). - وظيفة بموقع فارغ/مفقود → تجتاز (البيانات المفقودة لا تُعاقَب).
- مطابقة كلمة مفتاحية
block→ مرفوضة (block يتقدم على allow). allowفارغ → تجتاز (block أزالها بالفعل).allowغير فارغ → يجب مطابقة كلمة مفتاحية واحدة على الأقل.
مفتاح على مستوى المشروع في portals.yml (أخ لـ title_filter، غير متداخل تحت russian_portals). استخدمه لإسقاط الوظائف التي اجتازت مرشح العنوان لكنها في منطقة لا تستطيع قبولها.
ابدأ بـ 3–5 كلمات مفتاحية إيجابية للوضوح؛ وسّع لاحقاً.
content_filter (اختياري — web-ui 1.75.0، الأب #974). مفتاح على مستوى المشروع،
أخ لـ location_filter، بنفس قائمتي الكلمات المفتاحية positive / negative،
لكنه يُطابَق مع نص الوصف / المقتطف للوظيفة بدلاً من موقعها:
content_filter:
positive: ["python", "machine learning"]
negative: ["security clearance", "on-site only"]
دلالات مطابقة لـ location_filter: لا مفتاح → كل شيء يجتاز؛ وظيفة بوصف فارغ/مفقود
تجتاز (البيانات المفقودة لا تُعاقَب)؛ تطابق negative → مرفوضة؛ positive فارغ →
يجتاز؛ positive غير فارغ → يجب أن يطابق كلمة مفتاحية واحدة على الأقل (سلسلة فرعية
دون حساسية لحالة الأحرف). يُطبَّق بواسطة مسحَي ATS والمسح الإقليمي معاً. يؤثر فقط على
المصادر التي تُرسل وصفاً/مقتطفاً (مثل RSS) — أي وظيفة أخرى تجتاز — لذا فإن تفعيله لا
يُسقط أبداً صفوفاً بصمت من مصادر لا تحمل نصاً. استخدمه لإسقاط وظيفة اجتازت مرشح العنوان
لكن نصها يكشف عاملاً مانعاً.
search_queries
search_queries:
- name: "Greenhouse — Rails Engineer"
query: 'site:job-boards.greenhouse.io "Rails Engineer" OR "Ruby on Rails" remote'
enabled: true
- name: "Ashby — Senior Backend"
query: 'site:jobs.ashbyhq.com "Senior Backend" remote'
enabled: false
تُشغّل search_queries مسح الخيار B المدعوم بالذكاء الاصطناعي (/career-ops scan داخل Claude Code / Codex). لا تُنفَّذ بواسطة npm run scan الداخلي (الذي يضرب فقط APIs البوابات العامة). استخدمها عندما تريد اكتشاف أدوار في شركات غير موجودة في tracked_companies بعد. اضبط enabled: false للإبقاء على إدخال بدون تشغيله.
tracked_companies
tracked_companies:
- { name: Stripe, enabled: true, careers_url: https://job-boards.greenhouse.io/stripe }
- { name: Linear, enabled: true, careers_url: https://jobs.ashbyhq.com/linear }
- { name: JetBrains, enabled: true, careers_url: https://jobs.lever.co/jetbrains }
الحقول المطلوبة لكل إدخال: name وcareers_url. اختيارية: api (نقطة نهاية Greenhouse / Ashby / Lever / Workable / SmartRecruiters / Workday صريحة)، enabled: true|false للتضمين/الإقصاء دون حذف الإدخال. يكتشف الماسح الـ ATS من نمط URL (job-boards.greenhouse.io/<slug> → Greenhouse، إلخ) ويجلب boards-api العامة لكل شركة مباشرةً. الشركات بلا ATS قابل للتعرف تُتجاهل (بطاقة الشركات النشطة في /#/scan تعرضها بالرمادي مع ○).
rss (بوابات RSS / Atom)
tracked_companies:
- { name: LaraJobs, enabled: true, provider: rss, rss: https://larajobs.com/feed }
- { name: WeWorkRemotely, enabled: true, provider: rss, rss: https://weworkremotely.com/remote-jobs.rss }
وجّه الماسح إلى أي لوحة وظائف تنشر تغذية RSS/Atom (LaraJobs وWeWorkRemotely وRemoteOK وgolangprojects وغيرها) بإضافة إدخال مع provider: rss بالإضافة إلى مفتاح rss: (أو feed_url:) — دون تغييرات برمجية. مُكيّف RSS يُحلّل كل <item> (CDATA + كيانات HTML، العناوين/شعارات الشركات مُجرَّدة من علامات HTML)، يُوحّده إلى وظيفة، ويُشغّل نفس تدفق title_filter / location_filter + إزالة التكرار + إلحاق الخط الوظيفي كمصادر ATS. RSS يظهر بعدها كمصدر قابل للاختيار في القائمة المنسدلة للتصفية في #/scan. (web-ui v1.62.x)
russian_portals
russian_portals:
sources: ["hh", "habr", "trudvsem", "getmatch", "geekjob"] # أو واحد فقط
area: 113 # 1=موسكو، 2=بطرسبرغ، 113=روسيا، 1001=عن بُعد
per_page: 50
only_remote: false
queries:
- "Senior PHP"
- "Senior Go"
- "Тимлид PHP"
queries هي مطابقات جزئية غير حساسة لحالة الأحرف مقابل عناوين الوظائف على hh.ru وHabr Career. احذر من التداخل مع القائمة السلبية — إذا كانت "Senior PHP" في queries لكن "php" تنتهي في title_filter.negative، سيُعيد المسح صفراً من النتائج وسيُحذّرك المحرر من التعارض.
دليل الإعداد التفصيلي للبوابات الروسية
يشحن v1.29.0 مع 5 مُكيّفات للغة الروسية. اثنان لا يحتاجان سوى UA الافتراضي (habr-career، كشط HTML؛ trudvsem، API بيانات مفتوحة حكومية — لا مفتاح، لا قيد IP). اثنان كشط HTML للوحات تقنية (getmatch وَgeekjob — أيضاً بلا مفتاح). واحد هو hh.ru API الأساسي الذي قد يعيد 403 من IPs غير روسية إلا إذا ضبطت متغير بيئة HH_USER_AGENT عبر إعدادات التطبيق → مفاتيح API والبيئة التشغيلية (أو شغّلت الخادم من IP/VPN روسي).
قائمة المصادر
| مفتاح المصدر | الاسم المعروض | النوع | المصادقة | القيود الجغرافية |
|---|---|---|---|---|
hh |
hh.ru | JSON API | HH_USER_AGENT اختياري |
IPs غير الروسية قد تعيد 403 |
habr |
Habr Career | HTML | لا شيء | لا شيء |
trudvsem |
Trudvsem | JSON API (بيانات مفتوحة) | لا شيء | لا شيء |
getmatch |
GetMatch | HTML | لا شيء | لا شيء |
geekjob |
GeekJob | HTML | لا شيء | لا شيء |
الخطوة 1 — افتح portals.yml
يقع الملف في جذر career-ops/ الأب (ليس داخل web-ui/). إن لم يكن موجوداً بعد، انسخ المثال المشحون مع المشروع الأب:
# من جذر career-ops/ الأب (ليس web-ui/)
cp templates/portals.example.yml portals.yml
$EDITOR portals.yml
الخطوة 2 — تفعيل جميع المصادر الـ 5
أضف أو حدّث كتلة russian_portals لتسرد كل مصدر تريد مسحه. الترتيب في المصفوفة غير مهم؛ يسير الماسح بترتيب السجل.
russian_portals:
sources: ["hh", "habr", "trudvsem", "getmatch", "geekjob"]
area: 113 # 1=موسكو، 2=بطرسبرغ، 113=روسيا، 1001=عن بُعد
per_page: 50 # عدد الوظائف لكل استعلام لكل مصدر
only_remote: false # اضبط true للاحتفاظ بالوظائف عن بُعد فحسب
queries:
- "Senior PHP"
- "Senior Go"
- "Backend Senior"
- "Тимлид PHP"
الخطوة 3 — ضبط الاستعلامات والمرشحات
queries هي السلاسل التي يستخدمها الماسح للبحث في كل مصدر. كل استعلام يعمل مرة على كل مصدر — 4 استعلامات × 5 مصادر = 20 استدعاءً لكل مسح. حافظ على القائمة مركّزة (3–7 استعلامات) لإبقاء وقت المسح أقل من دقيقة. area هو رمز منطقة hh.ru (المصادر الأخرى تتجاهله). per_page يُقيّد عدد الوظائف التي يعيدها كل مصدر لكل استعلام. only_remote: true يُصفّي كل نتيجة لتقتصر على العمل عن بُعد على مستوى المُكيّف (الجدول لا يزال يحتوي على شريحة عن بُعد منفصلة).
الأخطاء الشائعة
تعارض القائمة السلبية. إذا ظهرت كلمة من استعلام ("php" أو "senior") في title_filter.negative، تُصفَّى كل النتائج قبل أن تراها. يُصدر الماسح تحذير تعارض في stderr وقت المسح — ابحث عن السطر ⚠ config: query "Senior PHP" contains "php" which is in the negative list. الإصلاح بحذف الكلمة المتعارضة من negative:
title_filter:
positive: [backend, senior, lead, php, go, golang, python]
negative: [junior, intern, frontend, ios, android]
russian_portals:
queries:
- "Senior PHP" # ✓ — "php" لم تعد في القائمة السلبية
- "Senior Go"
تعطيل مصدر واحد مؤقتاً
لتعطيل مصدر دون حذف بياناته، فقط أزل مفتاحه من sources:
russian_portals:
sources: ["hh", "habr", "trudvsem"] # 3 من أصل 5 مصادر ستعمل فحسب
التحقق من الإعداد
بعد حفظ portals.yml:
# 1. احفظ portals.yml.
# 2. في SPA، انتقل إلى #/scan.
# 3. انقر 🌐 مسح الآن.
# 4. راقب سجل SSE لسطر كل مصدر لكل استعلام:
# "Senior PHP"
# hh.ru 18
# habr 21
# trudvsem 3
# getmatch 0
# geekjob 2
# قيمة 0 طبيعية لبعض الاستعلامات — هذا يعني فحسب أن
# ذلك المصدر لم يجد تطابقات. سطر "geo-blocked" أو "timeout" يعني
# أن المُكيّف وصل إلى الموقع لكنه لم يستطع قراءة النتائج.
تدفق تهيئة CLI (scan-job-portals)
الإعداد الأساسي لـ career-ops (يُشغَّل مرة من جذر المشروع الأب):
cp templates/portals.example.yml portals.yml
$EDITOR portals.yml
هذا هو الإعداد بالكامل. حرّر الأقسام الثلاثة (title_filter وtracked_companies وsearch_queries واختيارياً russian_portals)، احفظ، وأنت مستعد للمسح.
سلوك إعداد SPA
عند أول تشغيل يُلحق الخادم كتلة russian_portals: موثّقة في portals.yml إن كانت مفقودة — عملية لاضئة (التشغيل الثاني لا يفعل شيئاً لوجود سطر russian_portals: الحرفي الآن). الأقسام الإنجليزية لا تُحقن تلقائياً؛ تأتي من templates/portals.example.yml الذي نسخته وفق الإعداد الأساسي أعلاه.
6. الصحة (#/health)
كل بوابة إعداد، في شارات موافق / اختياري / فشل. اقرأ هذا قبل رفع أي مشكلة “لا يعمل”.
استخدام الذكاء الاصطناعي وتكلفته. تعرض صفحة استخدام الذكاء الاصطناعي (💳، بجوار الصحة) رموز التوليدات الحيّة لكل مزوّد خلال 24س/7أ/30ي/الكل، مع تكلفة تقديرية بالدولار من جدول أسعار قابل للتعديل (لا تُحتسب فاتورةً). كما يُثبَّت مقياس الاستخدام مضغوط أسفل الشريط الجانبي الأيسر في كل صفحة — نفس إجماليات الرموز لـ24 ساعة/7 أيام/30 يومًا وتكلفة تقديرية لـ24 ساعة، يُحدَّث مباشرةً؛ وتبقى القائمة دائمًا ظاهرة فوقه، والنقر على رأسه يطويه.
الفحوصات المطلوبة (النظام لا يعمل بدونها)
Node version≥ 18 — يستخدم الخادمfetchالأصلية وnode:test.Project root— أنCAREER_OPS_ROOT(متغير بيئة أو اكتشاف تلقائي) موجود.cv.mdوconfig/profile.ymlوportals.ymlوdata/applications.mdوdata/pipeline.mdوmodes/oferta.md.
الفحوصات الاختيارية (تحذيرات فقط)
Profile customized—candidate.full_nameليس عنصر وهمي قياسياً.GEMINI_API_KEY/ANTHROPIC_API_KEY— مضبوطان في.env.(الخادم يستخدم UA الافتراضي)— يهم فقط إذا مسحت hh.ru من خارج روسيا.Playwright (node_modules الأب)— مطلوب لتوليد PDF وcheck-liveness.mjs. ثبّته بـcd $CAREER_OPS_ROOT && npm install && npx playwright install chromium.Parent project dependencies—cd $CAREER_OPS_ROOT && npm installإن كانت مفقودة.- مجلدات
data/وreports/وoutput/وjds/— تُنشأ تلقائياً عند أول كتابة.
عند كشف الخادم خارج loopback (HOST=0.0.0.0) تُستبدل المسارات المطلقة وإصدار Node الدقيق بـ "hidden" في الرد لئلا يُعرّف جار فضولي تثبيتك.
أزرار التشغيل
- ▶ Doctor يشغّل
node doctor.mjsويعرض المخرجات في نافذة منبثقة. - ▶ التحقق من الخط يشغّل
node verify-pipeline.mjs.
7. المسح (#/scan)
يزحف الماسح على كل بوابة مفعّلة، يُزيل التكرار مقابل تاريخك، ويكتب النتائج في data/last-scan.json وdata/pipeline.md.
البحث + الاستبعاد. يعامل مربع البحث الفواصل كـ«أو» («الأدوار المطلوبة»)؛ ويُخفي حقل الاستبعاد الجديد الصفوف المطابقة لأي كلمة مفصولة بفواصل. ويُحفَظ كلاهما مع عمليات بحثك.
مسح بنقرة واحدة (SPA)
🌐 مسح يُشغّل كل مصدر مفعّل في تمريرة واحدة:
- Greenhouse / Ashby / Lever / Workable / SmartRecruiters / Workday (المسح ATS) لكل شركة في
tracked_companiesبـ URL ATS قابل للتعرف. - مُجمّعات v1.75.0 لكل إدخال
tracked_companiesيختارها: RemoteOK / Remotive / Working Nomads (تغذيات عمل عن بُعد على مستوى اللوحة،provider: <slug>) وَ IBM / Arbeitsagentur / Glints / Jobstreet · SEEK (مدفوعة بالإعداد، كتلة<provider>:لكل إدخال). - hh.ru API + Habr Career + Trudvsem + GetMatch + GeekJob لكل استعلام في
russian_portals.
مرحلتان، نقرة واحدة (v1.29.2). زر 🌐 المسح الواحد يُشغّل كلاً من المسح ATS والمسح الإقليمي في دفق SSE واحد. ستلاحظ ترويستَي مرحلتين في السجل، بالترتيب:
▶ مسح ATS (Greenhouse + Ashby + Lever)— بوابات ATS الإنجليزية.▶ المسح الإقليمي (hh.ru + Habr Career)— 5 مصادر روسية من السجل.
تنتهي كل مرحلة بملخص ✓ done · NEW=N. إن رأيت مرحلة ATS فحسب، إصدارك أقدم من v1.29.2 — قم بالتحديث. قبل v1.29.2 كان عميل SSE يُغلق عند أول حدث done والمرحلة الإقليمية تُسقط صامتةً (tests/scan-stream-multi-phase.test.mjs هو شبكة الحماية من الانحدار).
يبث سجل SSE المباشر إلى اللوحة اليمنى أثناء عمل المسح. انقر إيقاف (أو انتقل بعيداً) للإلغاء — يُلغي الخادم طلبات HTTPS الجارية عبر AbortController.
تصفية النتائج
أسفل السجل، يعرض جدول النتائج صفوفاً من data/last-scan.json.
v1.78.1 — تحديث تلقائي مباشر. جدول النتائج الآن يتحدّث تلقائياً أثناء تشغيل المسح ومرة أخرى فور انتهائه — دون إعادة تحميل يدوية أو تبديل للصفحة.
v1.80.0 — Max per source وحجر المصدر. يحدّ حقل Max per source بجانب زر المسح عدد الوظائف التي تساهم بها كل لوحة (فارغ/0 = بلا حد، وهو الافتراضي) — مفيد عندما تطغى لوحة ضخمة واحدة على غيرها. وبشكل منفصل، أي مصدر يُعيد 404 / 410 دائماً يُكتب إلى
data/scan-quarantine.jsonويُتجاوز في عمليات المسح اللاحقة (شفاء ذاتي: يُعاد المحاولة بعد 14 يوماً)، فتتوقف الـ slug الميتة عن إغراق السجل. عطّله بـscan_quarantine: falseفيportals.yml.
المرشحات:
- نص حر — مطابقة جزئية مقابل العنوان / الشركة.
- قائمة المصدر المنسدلة — Arbeitsagentur / Ashby / BambooHR / Breezy HR / Comeet / GeekJob / Glints / Greenhouse / GetMatch / Habr Career / hh.ru / IBM / Jobstreet · SEEK / Lever / Personio / Recruitee / RemoteOK / Remotive / RSS / SmartRecruiters / SolidJobs / Teamtailor / Trudvsem / We Work Remotely / Workable / Workday / Working Nomads (تُملأ تلقائياً من
GET /api/scan/sources). - قائمة عن بُعد / هجين / حضوري المنسدلة.
- قائمة Country المنسدلة (v1.78.0) — مرشّح جغرافي يُملأ من الدول المكتشَفة عبر النتائج الحالية، كلٌّ معروضة مع إيموجي علَمها وعدّاد (مثل
🇩🇪 Germany (12)). اختر واحدة لتُبقي فقط الأدوار المرتبطة بتلك الدولة. يربط الاكتشاف الموقعَ النصّي الحر للإعلان (أسماء الدول/الأسماء البديلة + ~100 من كبرى مدن سوق العمل) بدولة؛ وهو متحفّظ ولا يخمّن أبداً، لذا فإن الإعلان الذي يتعذّر تحديد موقعه — أو إعلان “Remote” خالص — يبقى ضمن All countries. اجمعها مع قائمة نمط العمل المنسدلة للعثور على الأدوار المرتبطة بدولة و الأدوار عن بُعد. - قائمة Posted within المنسدلة (v1.80.0) — مرشّح عمر من جانب العميل (آخر 24 ساعة / 7 أيام / 30 يوماً). تُخفى الصفوف التي يكون
pubDateفيها أقدم؛ أما الصفوف بلا تاريخ مُدرَج فتمرّ (البيانات المفقودة لا يُعاقَب عليها). - ★ المفضّلة (v1.80.0) — انقر على ☆ في أي صف لتمييز وظيفة بنجمة (تُخزَّن في
localStorageحسب الرابط)؛ فعّل ★ المفضّلة في لوحة المرشحات لعرض الصفوف المميَّزة بنجمة فقط. تبقى النجوم بعد عمليات المسح وإعادة التحميل. - عمليات البحث المحفوظة (v1.80.0) — الشريط فوق المرشحات: سَمِّ مجموعة المرشحات الحالية ثم اضغط 💾 حفظ، ثم أعِد تطبيقها من القائمة المنسدلة أو 🗑 احذفها. تُخزَّن في
localStorage؛ وأي قيمة تالفة/معدَّلة تُعاد بسلاسة إلى الفراغ. - شرائح التقنية (PHP / Go / Backend / Senior / …) — مُكتشَفة تلقائياً لكل صف بواسطة
Skills.detectTechوSkills.detectLevel. تقاطع متعدد الاختيارات — اختيارPHP + Seniorيعرض الصفوف التي تحتوي على كليهما. - شرائح ديناميكية أسفل الشرائح الثابتة — أعلى 25 رمزاً مُكبَّراً متكرراً في العناوين، حتى تتكيف الواجهة مع الأدوار التي تمسحها فعلاً (تسويق، تصميم، مالية…) بدلاً من الانحصار في قاموس مهندس الخلفية.
بطاقة الشركات النشطة
بطاقة قابلة للطيّ تسرد كل شركة في portals.yml مع حالة مسحها:
- علامة ✓ خضراء — دعم مباشر لـ API (Greenhouse / Ashby / Lever / Workable / SmartRecruiters / Workday).
- علامة ○ رمادية — الاحتياطي لـ prompt البحث عبر الويب (لا تطابق API).
انقر اسم الشركة ← يملأ مرشح النتائج أعلاه بذلك الاسم. انقر أيقونة ↗ ← يفتح careers_url الخاصة بالشركة في تبويب جديد.
تدفق المسح عبر CLI (scan-job-portals)
طريقتان للمسح من جهة CLI (كلتاهما تودع روابط في data/pipeline.md الذي يقرأه SPA):
الخيار أ — سكريبت مباشر (~30 ثانية، صفر رموز AI):
npm run scan # كل بوابات Greenhouse/Ashby/Lever
npm run scan -- --dry-run # معاينة بدون حفظ
npm run scan -- --company Anthropic # تضييق على شركة متتبّعة واحدة
يعمل فقط لـ Greenhouse / Ashby / Lever / Workable / SmartRecruiters / Workday (روابط ATS قابلة للتعرف). لا رموز AI تُستهلك — يضرب APIs البوابات العامة مباشرةً.
الخيار ب — مسح مدعوم بالذكاء الاصطناعي:
/career-ops scan
داخل Claude Code / Codex / Cursor / Gemini CLI. يستخدم رموز النموذج. يزور كل صفحة في tracked_companies مباشرةً ويستطيع اكتشاف البوابات غير الـ API (صفحات الوظائف، ATS مخصص، بوابات إقليمية). أبطأ لكنه أوسع. مفيد عندما يعيد مسح ATS صفراً لهدف تعرف أنه يوظّف.
المخرجات (كلا المسارين) — روابط الإعلانات الجديدة مُلحَقة في data/pipeline.md، كل رابط تمت زيارته مُسجَّل في data/scan-history.tsv (إزالة التكرار عبر كل عمليات المسح المستقبلية)، ملخص مطبوع: الشركات الممسوحة · الوظائف الموجودة · المصفّاة بالعنوان · المكررات المتخطاة · العروض الجديدة المضافة.
عتبات الإجراء حسب الدرجة (تُطبَّق بعد /career-ops pipeline لتقييم الروابط الجديدة دفعةً):
| الدرجة | الخطوة التالية الموصى بها |
|---|---|
| ≥ 4.5 | /career-ops apply — توافق عالٍ، تقدّم فوراً |
| 4.0 – 4.4 | تقدّم، أو /career-ops contacto للحصول على توصية دافئة |
| 3.5 – 3.9 | /career-ops deep — ابحث أولاً |
| < 3.5 | تجاهل إلا لسبب شخصي محدد |
يُبرز #/dashboard و#/tracker في SPA كل صف يبلغ 4.0 فأكثر لتختار الإجراء دون إعادة تشغيل أي شيء.
أوامر المتابعة
بعد التقييم، المتابعات الأساسية هي:
/career-ops apply— ملء الطلب بإجابات مخصصة/career-ops contacto— صياغة تواصل عبر LinkedIn / البريد الإلكتروني/career-ops deep— بحث معمّق عن الشركة / الدور/career-ops tracker— عرض حالة الخط الوظيفي
hh.ru — المسح من الموقع الإلكتروني (منذ يوليو 2026 يلزم عنوان IP روسي)
يُمسح hh.ru بقراءة موقع البحث العام (hh.ru/search/vacancy)، تمامًا مثل Habr Career — بلا مفتاح ولا إعداد. لكن منذ يوليو 2026 يعيد hh.ru الرمز HTTP 451 (حجب قانوني إقليمي) لعناوين IP خارج روسيا، لذا لا يعمل المسح إلا من عنوان IP روسي — شغّل الخادم من روسيا أو عبر VPN بنقطة خروج روسية. عند أول 451 (أو 403 لمكافحة الروبوتات) يعطّل الماسح hh.ru لبقية التشغيل ويذكر ذلك في السجل، فتكتمل بقية المصادر الروسية بشكل طبيعي. لا تُستخدم واجهة JSON API (api.hh.ru) عمدًا: فهي تعيد 403 forbidden لأي عميل برمجي أيًا كان عنوان IP أو الـ User-Agent.
حتى من شبكة تبدو صحيحة، قد يصنّف hh.ru عنوان IP الخارج كـ VPN/بروكسي (أي IP لمركز بيانات/استضافة يُحتسب) ويعيد توجيه الفحص عبر 302 إلى صفحة بينية /vpncheeck (“VPN мешает работе сайта”) تعيد HTTP 200 مع صفر وظائف. يكتشف الماسح هذا التوجيه، ويعطّل hh.ru لبقية التشغيل، ويذكر ذلك في السجل. الحل على جانب الشبكة: تأكد من أن الترافيك يخرج فعلًا عبر IP سكني — كثيرًا ما يبقى VPN أو بروكسي على مستوى النظام نشطًا حتى مع إيقاف مفتاح المتصفح (تحقق من IP الخروج الحقيقي، مثلًا عبر api.ipify.org).
8. الخط الوظيفي (#/pipeline)
صندوق وارد يضم روابط URL بانتظار التقييم. يعيش في data/pipeline.md.
شريط النظرة العامة. يعرض شريط مضغوط في الأعلى مسارك بنظرة واحدة — كم عدد الروابط في الوارد، وكم متتبَّع، وأعداد Applied/Responded/Interview/Offer، وكل منها يربط بالمتتبِّع.
إضافة روابط URL
ثلاث طرق:
- اكتب أو الصق رابطاً في حقل الإدخال + انقر + إضافة.
- استخدم البحث العام في الشريط العلوي (شارته تقرأ Enter): الصق أي رابط
http(s)://…واضغط Enter لفتح الـ auto-pipeline؛ اكتب أي نص آخر وEnter ينتقل إلى#/scanمع تعبئة ذلك المصطلح مسبقاً (v1.78.1). لا يزال Ctrl/Cmd+K يركّز الحقل حيثما يسمح المتصفّح. وشعار العلامة التجارية يعود إلى لوحة المعلومات. - شغّل مسحاً (انظر أعلاه) — تذهب الإعلانات الجديدة إلى الخط الوظيفي تلقائياً.
كل رابط يمر عبر isValidJobUrl() من جانب الخادم. الحلقات الداخلية (localhost، 127.0.0.1)، file://، javascript:، العناوين الحرفية IP، والنصوص التي تحتوي على محارف قوالب (<، >، ") تُعيد 400.
لوح معاينة جانب الخادم
انقر أي صف في الخط الوظيفي لتحميل معاينة على اليمين. معظم لوحات ATS لا تُرسل رؤوس CORS لذا لا يستطيع المتصفح جلبها مباشرةً؛ الخادم يُوكّل الطلب، ويُزيل <script> / <style> / وسوم HTML، ويُعيد ما يصل إلى 8 كيلوبايت من النص العادي.
وكيل المعاينة يتتبع عمليات إعادة التوجيه يدوياً مع التحقق من SSRF لكل خطوة — كل رأس Location يمر عبر isValidJobUrl() مجدداً، بحيث لا يستطيع لوح معادٍ إرسالك إلى حلقة داخلية / IP خاص / file://. الحد الأقصى 3 خطوات، مهلة 15 ثانية.
إجراءات الصف
- ▶ — الانتقال إلى
#/evaluate?url=…مع الرابط مُملوءاً مسبقاً. - ✕ — حذف الرابط من
data/pipeline.md.
أزرار أعلى اليمين
- ⚡ تقييم الأول — فتح أول رابط في قائمة الانتظار على صفحة التقييم جاهزاً للتقييم.
- مسح — العودة إلى الماسح إذا أردت المزيد من الروابط.
9. التقييم (#/evaluate)
يُقيّم توصيف وظيفي واحداً مقابل cv.md وconfig/profile.yml. يُعيد تقييماً منظماً A–G وفق modes/oferta.md مع درجة من 0 إلى 5.
المدخلات
الصق توصيف الوظيفة في منطقة النص، أو انتقل من #/pipeline مع ?url=<href> — تجلب الصفحة الرابط عبر نفس الوكيل الآمن من SSRF المستخدم لمعاينات الخط الوظيفي وتُملئ منطقة النص مسبقاً.
انقر 💾 حفظ توصيف الوظيفة لحفظ التوصيف في jds/jd-<date>-<ts>.txt لمسار التدقيق (أو مرّر save: true في استدعاء API — نفس الأثر).
سلسلة الاحتياط
- Anthropic — مُفضَّل عند ضبط
ANTHROPIC_API_KEY. يُجمّع الخادمcv.mdوconfig/profile.ymlوmodes/_shared.mdوmodes/oferta.mdفي كتلة<project_context>قبل الـ prompt (كل ملف محدود بـ 16 كيلوبايت، الـ prompt الكامل محدود بـ 200 كيلوبايت). يُعيد markdown مستنداً للصفحة مباشرةً. - Gemini — عند ضبط
GEMINI_API_KEYفقط. الخادم يُشغّلgemini-eval.mjsمع توصيف الوظيفة كملف مؤقت. نموذج المستوى المجاني (gemini-2.0-flash) مناسب للتقييم الروتيني. - يدوي — بدون مفتاح. تُعيد الصفحة prompt مُشكَّلاً بالكامل يمكنك لصقه في Claude Code أو ChatGPT أو أي LLM آخر.
أقسام المخرجات (مخطط career-ops.org القياسي A-F)
إعادة محاذاة v1.15.0. حروف الكتل تطابق الآن مخطط career-ops.org القياسي. التقارير السابقة لـ v1.15 استخدمت A–G (مع
C=المخاطر،F=الحكم،G=المشروعية)؛ لا نزال نُصيّرها كما هي للتوافق مع الإصدارات السابقة، لكن التقارير الجديدة تُصدر A–F بالمعنيات القياسية أدناه. الدرجة والمشروعية الآن في ترويسة التقرير (score: 4.2/5،legitimacy: High|Medium|Low).
A. ملخص الدور — ملخص بثلاث نقاط (المخاطر مُشار إليها داخلياً).
B. تطابق السيرة الذاتية — أعلى 3 مهارات متطابقة + أعلى 3 مهارات مفقودة.
C. الاستراتيجية — التوصية: تقدم الآن / contacto أولاً / deep أولاً / تخطَّ. كانت المخاطر قبل v1.15.
D. التعويض — مقارنةً بـ target.comp_total_min_usd (القديم) أو compensation.target_range (القياسي).
E. التخصيص — الزاوية للتصدير بها، الإطار حسب النمط الوظيفي، النقاط التي يُشار إليها في خطاب التغطية / التواصل. كانت استراتيجية التقديم قبل v1.15.
F. قصص STAR — 1–3 كتل S-T-A-R جاهزة للصق مخصصة للدور. كانت الحكم (الدرجة الخام) قبل v1.15؛ الدرجة الآن في ترويسة التقرير جانب legitimacy.
حفظ التقرير
انقر 💾 حفظ التقرير (أو استخدم مبدّل الحفظ في استدعاء API) لحفظ markdown في reports/<date>-<company>-<role>.md. ترويسة التقرير المُحلَّلة (الدرجة / المشروعية / الرابط) تظهر على صفحة التقارير ولوحة التحكم.
التقييم الدفعي عند وجود 10 توصيفات أو أكثر
لتوصيف وظيفي واحد، صفحة #/evaluate هي الأداة الصحيحة. لـ 10+ روابط في قائمة الانتظار بالخط الوظيفي، يصبح النقر على كل توصيف أمراً غير عملي — انتقل إلى القسم الفرعي التقييم الدفعي في §14 (تشغيل ./batch/batch-runner.sh من الأب)، دعه يعمل طوال الليل، ثم عد إلى #/reports / #/tracker للنتائج. التدفق الكامل: batch-evaluate-offers.
10. التقارير (#/reports)
تصفح كل تقييم محفوظ. البطاقات تُظهر العنوان والتاريخ وعلامة المشروعية والدرجة (مُلوَّنة: أخضر ≥ 4.0، أصفر ≥ 3.0، أحمر أدناه).
انقر بطاقة لقراءة markdown الكامل. ترقيم الصفحات: 12 لكل صفحة؛ عناصر تحكم في الأسفل.
عرض التقرير الفردي يحتوي أيضاً على:
- ← كل التقارير — العودة إلى الشبكة.
- 🔗 فتح توصيف الوظيفة — يفتح إعلان الوظيفة الأصلي في تبويب جديد.
11. المتتبع (#/tracker)
نظام CRM. صف واحد لكل طلب توظيف؛ يعيش في data/applications.md كجدول GitHub-Flavored Markdown.
تدفق الحالة
Evaluated ← Applied ← Responded ← Interview ← Offer / Hired / Rejected / Discarded / SKIP.
Hired (الإصدار v1.118.0) هي الحالة النهائية السعيدة — تم قبول العرض. يميّزها المتتبِّع بشارة احتفالية ويستقبلها بلافتة «حصلت على الوظيفة».
القائمة البيضاء للحالات مُطبَّقة من جانب الخادم؛ إرسال أي شيء آخر في POST /api/tracker يُعيد الحالة افتراضياً إلى Evaluated. التحول القياسي Evaluated → Applied تلقائي عند تأكيد Submitted. في نهاية /career-ops apply (انظر §14).
تخطيط الأعمدة
| العمود | ما هو |
|---|---|
# |
ترقيم تلقائي بصفر بادئ (001، 002، …). |
Date |
تاريخ ISO (YYYY-MM-DD). الافتراضي: اليوم. |
Company |
نص حر. الأنابيب (|) وأسطر جديدة مُهرَّبة تلقائياً. |
Role |
نفسه. |
Score |
تنسيق N/5 (مثلاً 4.2/5). |
Status |
قائمة مرقَّمة من قيم مسموحة. |
PDF |
✅ عندما تنجح generate-pdf.mjs لهذا الصف. |
Report |
رابط markdown للـ reports/*.md المطابق. |
Notes |
نص حر، محدود بـ 200 حرف. |
المرشحات
- قائمة الحالة المنسدلة.
- قائمة الدرجة المنسدلة —
≥ 4.0(عالية)،≥ 3.0(متوسطة)،< 3.0(منخفضة). - البحث — مطابقة جزئية عبر الشركة + الدور.
كل مرشح يُعيد ضبط رقم الصفحة إلى 1. 25 صفاً لكل صفحة.
أزرار الصيانة
- ▶ تطبيع يُشغّل
normalize-statuses.mjs— يُعيد توحيد هجاء الحالات (applied←Applied،interview←Interview). - ▶ إزالة التكرار يُشغّل
dedup-tracker.mjs— يُزيل التكرارات غير الحساسة لحالة الأحرف حسب(company, role). - ▶ دمج يُشغّل
merge-tracker.mjs— يسحب الإدخالات المعلقة منbatch/tracker-additions/*.tsv(حيث يُودع تدفق الدفعات الأبوي الطلبات المُقدَّمة عبر مساعد التقديم). يُزيل التكرارات ويُؤرشف الملفات المعالجة فيbatch/tracker-additions/merged/. انظر batch-evaluate-offers لتدفق الدفعات الصعودي.
إضافة صفوف
POST /api/tracker — الجسم { company, role, score?, status?, url?, reportSlug?, notes?, date? }. إزالة التكرار حسب (company, role) غير حساس لحالة الأحرف. من الواجهة، تُقدِّم صفحة التقييم زراً “إضافة إلى المتتبع” بعد درجة ناجحة.
12. البحث المعمّق (#/deep)
توليد ملخص شركة منظم: لقطة، ثقافة هندسية، أخبار حديثة، مشاعر Glassdoor، مسار المقابلة، نقاط نفوذ التفاوض، ثلاثة أسئلة ذكية لطرحها على المُجنِّد.
المدخلات
حقلان — اسم الشركة و(اختياري) الدور. قالب النمط (modes/deep.md) هو ما يُشكّل الهيكل.
مسارات المخرجات
نفس سلسلة الاحتياط في التقييم:
- Anthropic مباشر (مُفضَّل) —
bundleProjectContextيُضمِّن cv + profile +_shared.md+deep.md. المخرج: 10–30 كيلوبايت من markdown مستنداً يُحفظ فيinterview-prep/<company>-<role>.md. - Gemini مباشر — استدعاء
gemini-eval.mjs. نفس هدف الحفظ. - Prompt يدوي — تُسلِّمك الصفحة prompt جاهزاً لـ Claude Code (الذي يملك WebFetch + WebSearch ويستطيع إجراء بحث حقيقي).
نصائح
- Anthropic على
claude-sonnet-4-6يُعيد عادةً ~13 كيلوبايت من النص المفيد في 1–3 دقائق لكل استدعاء. - لا يملك Anthropic SDK بحثاً على الويب مدمجاً. للأدوار التي تحتاج أخباراً جديدة + مشاعر Glassdoor، الصق الـ prompt اليدوي في Claude Code ودعه يستخدم أداة WebFetch.
- تُحتسب الاستدعاءات المباشرة على الرصيد؛ استدعاء بحث معمّق واحد بـ Sonnet 4.6 يُكلِّف تقريباً 0.30–0.50 دولار.
13. نماذج النمط (صفحات /#/<mode> السبع)
لوحة الإيقاع (v1.117.0). تفتح صفحة المتابعة الآن بلوحة إيقاع حتمية تعتمد على followup-cadence.mjs من المشروع الأصل: الاستعجال لكل طلب (🔴 عاجل / 🟠 متأخر / 🟡 بانتظار / 🔵 بارد) مع الأيام حتى الخطوة التالية، إضافة إلى زر زرع تواريخ المتابعة الذي يثبّت تاريخ متابعة أولًا لكل صف Applied (followup-seed.mjs --backfill). دون سكربتات الأصل تعرض اللوحة بصدق «غير متاح».
سبعة منشئي prompt: أفكار المشروع، خطط التدريب، رسائل المتابعة، تقييمات الدفعات، التواصل مع المُجنِّدين، ملخصات إعداد المقابلة، وتحليل الأنماط الاسترجاعية. كل منها يُغلِّف قالب modes/<slug>.md محدداً:
| الصفحة | Slug | الغرض |
|---|---|---|
#/project |
project |
تخصيص مشروع محفظة لدور مستهدف. |
#/training |
training |
تحليل فجوة المهارات ← المنهج الدراسي. |
#/followup |
followup |
مسودة بريد إلكتروني بعد المقابلة. |
#/batch |
batch |
prompt تقييم دفعي متعدد التوصيفات. |
#/contacto |
contacto |
رسالة تواصل إلى مُجنِّد / مرجع. |
#/interview-prep |
interview-prep |
ملخص إعداد لجولة مقابلة محددة. |
#/patterns |
patterns |
“ما الأنماط التي جعلتني ناجحاً؟” تحليل استرجاعي. |
الشكل المشترك
كل صفحة تحتوي على نموذج صغير (الحقول خاصة بالنمط)، زر ▶ توليد prompt (يدوي)، وعند وجود مفتاح Anthropic أو Gemini — زر ⚡ تشغيل مباشر يُصبح الأساسي.
النقر على ▶ توليد prompt يُعيد الـ prompt المُجمَّع مع قيم نموذجك مُحوَّلة إلى JSON داخل كتلة User-supplied context:، يعقبها قالب modes/<slug>.md حرفياً. انسخ والصق في LLM من اختيارك.
النقر على ⚡ تشغيل مباشر يُرسل نفس الـ prompt إلى Anthropic (أو Gemini)، مع تضمين cv.md + profile.yml + _shared.md عبر bundleProjectContext. تُصيَّر النتيجة على الصفحة، قابلة للنسخ والتنزيل كـ .md.
الصفحات السبع قائمة مسموحة صريحة — الأنماط التي لها مسار مخصص (oferta ← التقييم، deep ← البحث المعمّق) والأنماط التي يدعمها المشروع الأبوي داخل Claude Code فقط (apply، scan، pipeline، tracker، pdf، latex، ofertas، auto-pipeline) تبقى خارج هذه الواجهة عمداً.
14. قائمة مراجعة التقديم (#/apply)
بمجرد اتخاذ قرار التقديم، تُولِّد صفحة مساعد التقديم هذه قائمة مراجعة للتقديم الفعلي. لا تملأ النماذج تلقائياً — ذلك التدفق يبقى في /career-ops apply داخل Claude Code الذي يستخدم Playwright في المشروع الأبوي.
وضع قائمة المراجعة في SPA (#/apply)
قائمة مراجعة SPA للمستخدمين الذين يُفضِّلون ملء النموذج يدوياً دون استدعاء Playwright. تُغطي:
- شغّل
/career-ops apply <url>في Claude Code لقراءة النموذج عبر Playwright (تخطَّ هذه الخطوة إذا كنت تُدخِل البيانات يدوياً). - تحقق أن الإعلان لا يزال نشطاً (
check-liveness.mjs). - تأكد أن السيرة الذاتية هي الأحدث (
cv-sync-check.mjs، ثم PDF إذا كانت الدرجة ≥ 4.0). - خصّص خطاب التغطية / إجابة “لماذا نحن؟” باستخدام نقاط إثبات STAR+R من
cv.md. - أجب على أسئلة EEO / الكفالة / تاريخ البدء بصدق.
- احفظ الإجابات المُعبَّأة في
interview-prep/{company}-{role}.mdقبل التقديم. - لا تُرسل تلقائياً أبداً — أنت (الإنسان) تنقر الزر النهائي.
- بعد التقديم: أضف صفاً إلى
data/applications.md(أو اكتب TSV فيbatch/tracker-additions/).
الملء اليدوي مقابل المساعد بـ Playwright
مساران للتقديم الفعلي:
- يدوي — افتح صفحة الوظائف في تبويب متصفح عادي، اتبع قائمة مراجعة SPA أعلاه، انسخ/الصق الإجابات. لا حاجة لـ Playwright. استخدمه عندما يكون النموذج قصيراً أو ليس لديك Chromium مثبتاً.
- المساعد بـ Playwright — شغّل
/career-ops apply <company>في Claude Code (المشروع الأبوي). يفتح Playwright متصفحه الخاص، يقرأ كل حقل نموذج، يُعيد إجابات مسودة مُرقَّمة. أنت لا تزال تنقر إرسال. استخدمه عندما يكون النموذج طويلاً أو ديناميكياً أو تريد مسار تدقيق الأسئلة وإجاباتها.
تدفق التقديم الكامل عبر CLI (apply-for-a-job)
المتطلبات المسبقة:
- شغّل
/career-ops pipelineأولاً حتى يكون للتوصيف تقرير تقييم تحتreports/. أمر التقديم يعتمد على تقييم موجود؛ بدونه، شغّل الخط الوظيفي أولاً. - احصل على التقرير والملف الشخصي محمَّلَين.
- مُوصى به: Playwright مُثبَّت (
npx playwright install chromium— انظر إعداد Playwright أدناه). يتراجع إلى WebFetch (معاينة نموذج نصية فقط، بدون نقر-ملء) عند غيابه.
التدفق المُرقَّم (8 خطوات قياسية):
-
شغّل الأمر مع اسم الشركة:
/career-ops apply <company>مثال:
/career-ops apply Anthropic. بدون وسيطة، قدّم لقطة شاشة للنموذج، النص الملصوق، أو رابط الطلب في الدور التالي. -
حدِّد التقرير. يجد النظام التقييم المطابق في
reports/(الذي أنشأه/career-ops pipelineأو#/evaluateسابقاً). -
افتح النموذج. يُطلق Playwright نافذة متصفح تلقائياً — لا تفتحها أنت.
-
اقرأ الحقول. يقرأ النظام ويُحلِّل كل حقل في النموذج (التسمية، النوع، مطلوب، الخيارات للقوائم المنسدلة).
-
ولِّد الإجابات. ينشئ career-ops ردوداً مخصصة لكل حقل بناءً على ملفك الشخصي ونقاط الإثبات والدور.
-
أعِد قائمة مُرقَّمة. تستلم إجابات مُرتَّبة لتطابق تخطيط النموذج — الحقول البسيطة (الاسم، البريد الإلكتروني) أولاً، الحقول النصية الحرة (خطاب التغطية، “لماذا نحن؟”) أخيراً. العناصر المُعلَّمة تُشير إلى أشياء تحتاج انتباهاً بشرياً — مثبِّت الراتب، تفاصيل سيرة ذاتية مفقودة، أسئلة اختيارية.
-
الملء اليدوي. تنسخ وتلصق كل إجابة في الحقل المقابل. هذه الخطوة يدوية وغير مؤتمتة. أنت تراجع كل إجابة أولاً.
-
المستخدم يُرسِل. أنت تنقر إرسال بنفسك. career-ops لا ينقر إرسال أبداً. أكّد الإتمام بكتابة في المحادثة:
Submitted.
التحديثات التلقائية عند Submitted.:
- تتحول الحالة
Evaluated → Appliedفيdata/applications.md. - الإجابات المُعبَّأة تبقى في القسم G من التقرير للمرجع المستقبلي.
التسليم إلى المتتبع:
/career-ops tracker
راقب حالة خطك الوظيفي بأكمله، بصرف النظر عن درجة الدور.
التقييم الدفعي (batch-evaluate-offers)
عندما يكون لديك 10+ توصيفات وظيفية لتقييمها دفعةً (صفحة SPA’s #/evaluate غير عملية لهذا الحجم)، استخدم مشغّل الدفعات من CLI.
ملف الإدخال — batch/batch-input.tsv (محدود بتبويب):
| العمود | الغرض |
|---|---|
id |
رقم تسلسلي فريد |
url |
رابط إعلان الوظيفة الكامل |
source |
المنصة المصدر (LinkedIn، Greenhouse، إلخ.) |
notes |
تفاصيل سياقية اختيارية |
مثال على صف:
1<TAB>https://jobs.example.com/senior<TAB>LinkedIn<TAB>
علامات ./batch/batch-runner.sh:
--dry-run— معاينة العروض المعلقة دون تقييم. شغّل هذا دائماً أولاً للتحقق من TSV.--parallel N— تشغيل N عمال في وقت واحد (1 أو 2 أو 3 مُوصى به).--min-score X.X— تخطّي حفظ العروض التي تحصل على أقل من العتبة. مفيد للاحتفاظ فقط بالتقارير للأدوار ذات التوافق العالي.--retry-failed— إعادة معالجة العروض التي أخطأت في التشغيل السابق فقط (أعطال شبكة، حدود معدل).--max-retries N— محاولة العروض الفاشلة حتى N مرة (الافتراضي: 2).--model NAME— نموذج Claude يُمرَّر إلىclaude -p --model(career-ops الأبوي 1.8.0، #504). غير مُعيَّن = افتراضي اشتراك Claude Max الخاص بك. استخدم نموذجاً أرخص للدفعات الكبيرة، مثلاًclaude-sonnet-4-6. يظهر في#/batchكحقل إدخال النموذج (web-ui 1.31.0).--start-from N— تخطّي معرِّفات العروض أقل من N (استئناف دفعة معالَجة جزئياً). يظهر في#/batchكحقل إدخال البداية من # (web-ui 1.31.0).
التسلسل القياسي:
-
حرِّر
batch/batch-input.tsv— صف واحد لكل توصيف. -
التشغيل التجريبي (مُوصى به أولاً):
./batch/batch-runner.sh --dry-run -
التشغيل — تسلسلي أو متوازٍ:
./batch/batch-runner.sh # واحد في المرة ./batch/batch-runner.sh --parallel 2 # اثنان في وقت واحد ./batch/batch-runner.sh --parallel 3 # ثلاثة في وقت واحد ./batch/batch-runner.sh --parallel 2 --min-score 4.0 # احتفظ فقط بالتوافق العالي -
إعادة محاولة الأعطال (شبكة / حدود معدل):
./batch/batch-runner.sh --retry-failed --max-retries 3 -
التقارير تُخزَّن في
reports/بصيغة{id}-{company}-{YYYY-MM-DD}.md. صفوف الملخص تُلحَق فيbatch/tracker-additions/. -
الدمج في المتتبع:
node merge-tracker.mjs # تطبيق إضافات الدفعة node merge-tracker.mjs --dry-run # معاينة الدمجأمر الدمج يُزيل التكرارات ويُؤرشف الملفات المعالجة في
batch/tracker-additions/merged/.
تُعرض التقارير الناتجة في SPA تحت #/reports (مُقسَّمة صفحات، مُلوَّنة حسب الدرجة) وصفوف المتتبع تحت #/tracker — تماماً كما لو أضفت كل واحدة عبر #/evaluate. اقرن مع زر الصيانة ▶ دمج في #/tracker إذا كنت تُفضِّل عدم النزول إلى CLI.
إعداد Playwright (set-up-playwright)
مطلوب لميزتَين في career-ops:
- ملء النموذج في
/career-ops apply(الخطوة 3 أعلاه — يفتح Playwright المتصفح، يقرأ تسميات الحقول، يقترح إجابات). - توليد PDF عبر
/career-ops pdfوزر SPA 📄 توليد PDF في#/cv/#/reports/:slug/#/evaluate/#/deep/#/interview-prep.
الاحتياطي عند غياب Playwright: تدفق التقديم يتراجع إلى WebFetch (معاينة نموذج نصية فقط، بدون نقر-ملء). توليد PDF يُخطئ ببساطة.
الإعداد الأساسي (شغّله من جذر career-ops الأبوي):
# تثبيت Chromium لـ Playwright
npm install
npx playwright install chromium
# تسجيل Playwright MCP حتى يتمكن Claude Code من قيادة النماذج
claude mcp add playwright npx @playwright/mcp@latest
# التحقق من المكوّنات الثلاثة (Chromium، مكتبة Playwright، MCP)
npm run doctor
تسجيل MCP البديل — أضف إلى .claude/settings.local.json:
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["-y", "@playwright/mcp@latest"]
}
}
}
ملاحظات السلوك:
- Headless بشكل افتراضي. يعمل Playwright بصمت. للمشاهدة الفعلية، أخبر Claude
افتح المتصفح عبر playwright واملأ النموذج بأكمله. - ثلاثة أدوار في حزمة واحدة — تثبيت npm لـ Playwright يمنحك مكتبة أتمتة المتصفح، محرك توليد PDF لـ
/career-ops pdf، و(عبر MCP) تدفق ملء النموذج داخل Claude Code. - تحقق قبل الاعتماد عليه —
npm run doctorيُؤكد عمل المكوّنات الثلاثة. صفحة السلامة في SPA تُظهر فحصPlaywright (parent node_modules)الذي يفشل سريعاً عند غيابه.
15. التحضير للمقابلة
هذه المرحلة تأتي بعد البحث المعمّق وقبل المقابلة مباشرةً. ثلاثة مخرجات في هذا التطبيق تتقاطع هنا:
- ملفات البحث المعمّق المحفوظة ضمن
interview-prep/، ملف واحد لكل زوج شركة-دور قمت بتشغيله. تصفّح من صفحة البحث المعمّق أو مباشرةً عبر/api/interview-prep. - وضع Patterns (
#/patterns) — يولّد prompt للتأمل الذاتي: “عبر آخر N مقابلة / عرض / رفض، ما الأنماط الثابتة؟” مفيد حين تراكمت لديك 5+ صفوف في المتتبّع. - وضع Interview-prep (
#/interview-prep) — يُنشئ ورقة موحّدة لجولة قادمة محددة (سلوكية، تقنية، تصميم أنظمة). يذهب الناتج إلى مجلدinterview-prep/نفسه.
سير العمل الموصى به
لكل مقابلة مجدولة:
- أعِد تشغيل Deep (أو افتح الملف المحفوظ) في اليوم السابق.
#/interview-prep— أنشئ ورقة موحّدة للجولة المحددة. الصقها في ملاحظاتك.- جولات تصميم الأنظمة / البرمجة — افتح
#/trainingواطلب مراجعة مركّزة لمدة 30 دقيقة على النظام الفرعي الذي يُركّز عليه الإعلان الوظيفي. - جولات التعويض — افتح ملف البحث المعمّق، وانتقل إلى “نقاط ضغط التفاوض”. أحضر 2–3 نقاط بيانات محددة (نطاق Glassdoor، التمويل الأخير، عرض مماثل من شركة أخرى).
- الجولات السلوكية — استخرج قصص STAR+R من
cv.mdالتي تقع في القسم B من تقرير التقييم الأصلي.
بعد المقابلة مباشرةً:
- حدّث صف المتتبّع: الحالة →
Responded(ثمInterview،Offer، إلخ). - شغّل
#/followupلصياغة بريد الشكر. - إن حصلت على معلومات جديدة (نطاق التعويض، تكوين الفريق، مفاجأة في التقنيات المستخدمة)، عدّل ملف
interview-prep/<company>-<role>.mdالمحفوظ بإضافة## ملاحظات ما بعد الجولةحتى يجد نسختك المستقبلية هذه المعلومات.
16. سجل النشاط + استكشاف الأخطاء
سجل النشاط (#/activity)
سجل تدقيق لكل طلب يغيّر الحالة ويصل إلى الخادم. يُسجّل: إضافات Pipeline، كتابات المتتبّع، حفظ CV، حفظ JD، تشغيلات التقييم، تشغيلات البحث المعمّق، تشغيلات المسح، تغييرات الإعداد، تشغيلات الوضع.
تُخفَى المفاتيح السرية (ANTHROPIC_API_KEY، GEMINI_API_KEY) عند الدخول؛ لن ترى قيمة مفتاح حقيقية في data/activity.jsonl أبداً.
تصفية حسب بادئة الإجراء (pipeline.، cv.، evaluate، scan.، إلخ). 25 صفاً في كل صفحة؛ يُعيد الخادم حتى 500 حدث الأحدث.
استكشاف الأخطاء وإصلاحها
| الأعراض | السبب المحتمل | الحل |
|---|---|---|
صفحة السلامة حمراء على cv.md |
أول تشغيل، الملف غير موجود | touch $CAREER_OPS_ROOT/cv.md ثم تحديث الصفحة. |
السلامة حمراء على Profile customized |
candidate.full_name لا يزال Jane Smith |
عدّل config/profile.yml. |
hh.ru: HTTP 403 في سجل المسح |
IP غير روسي، بدون (server uses default UA) |
سجّل في dev.hh.ru/admin، اضبط IP روسي / VPN. |
gemini-eval.mjs: ERR_MODULE_NOT_FOUND |
تبعيات المشروع الأصلي غير مثبّتة | cd $CAREER_OPS_ROOT && npm install. |
| أخطاء توليد PDF | Playwright غير مثبَّت في المشروع الأصلي | cd $CAREER_OPS_ROOT && npx playwright install chromium. |
/career-ops apply يقول “no report found” |
Pipeline لم يُقيّم هذا الإعلان | شغّل /career-ops pipeline (أو #/evaluate) أولاً؛ راجع المتطلبات في §14. |
batch-runner.sh: no such file |
التشغيل من مجلد خاطئ | cd $CAREER_OPS_ROOT قبل استدعاء ./batch/batch-runner.sh. |
الخادم يُبلّغ EADDRINUSE: 4317 |
نسخة قديمة لا تزال تعمل | pkill -f 'node server/index.mjs' ثم إعادة التشغيل. |
| استدعاء LLM المباشر يتعلّق أكثر من دقيقتين | Prompt ضخم أو Anthropic بطيء | تحقق من علامة Anthropic في /api/health؛ الخادم يحدّ الـ prompt بـ 200 KB ويُعيد 413. |
معاينة Pipeline تُظهر (unsafe redirect) |
الإعلان أعاد التوجيه إلى IP خاص / loopback | هذه ميزة أمان (REVIEW-B1). يُرفض هدف إعادة التوجيه ويبقى الرابط الأصلي دون تغيير. |
| نص صف المتتبّع يكسر الجدول | خط مائل في اسم الشركة قبل v1.9.1 | حدّث إلى v1.9.1+ — يُهرَّب الخط المائل من البداية إلى النهاية (BF-1). |
npm test يفشل على استنساخ جديد |
الاختبارات تفترض تخطيط المشروع الأصلي | استخدم CAREER_OPS_ROOT=$(mktemp -d) وهيّئ المصادر الوهمية. |
للتشخيص المعمّق: شغّل ▶ Doctor في صفحة السلامة، انسخ الناتج، وابحث في متتبّع المشكلات على https://github.com/Fighter90/career-ops-ui/issues.
17. كيفية إضافة مصدر بوابة وظائف جديد
يُعامِل career-ops-ui كل بوابة وظائف بوصفها محوّلاً — ملف واحد ضمن server/lib/sources/<slug>.mjs يعرف كيفية جلب نتائج هذه البوابة وتوحيد صيغتها. اعتباراً من v1.118.0 يشحن سجل server/lib/sources/ مع 59 محوّلاً — 54 إنجليزية + 5 روسية بوابات. تشمل المجموعة الإنجليزية أنظمة ATS الرئيسية (Greenhouse / Ashby / Lever / Workable / SmartRecruiters / Workday)، والمُجمّعات على مستوى اللوحة المُختارة عبر provider: صريح (RemoteOK، Remotive، We Work Remotely، NoDesk، Get on Board، Amazon، …)، وأنظمة ATS لكل مستأجر التي يُكتشف تلقائياً من مضيف careers_url أو من عنوان api: صريح (BambooHR، Personio، Recruitee، Teamtailor، Avature، SAP SuccessFactors، …). لا حاجة أبداً لعدّ القائمة الكاملة يدوياً هنا — إذ تُكتشف تلقائياً من server/lib/sources/ وتُعرض حيّةً في القائمة المنسدلة Source على #/scan. انظر §5 للـ YAML وَ docs/portals-examples.md للإدخالات الجاهزة للنسخ.
v1.69.0 (P-14) — اكتشاف تلقائي عند الإضافة. إضافة مصدر ثاني عشر الآن مجرد إسقاط ملف. لم يعد السجل (
server/lib/sources/registry.mjs) يحمل قائمة يُعدَّل فيها يدوياً — عند الإقلاع يفحص هذا المجلد (readdirSync+import()ديناميكي) ويجمع كتلةexport const metaمن كل*.mjs. اكتب المحوّل، أعلنmeta، وسيظهر فوراً في الماسح وقائمة الفلتر في#/scanوالـ RU dispatcher — دون تعديلregistry.mjs. (المصادر الروسية لا تزال تحتاج سطراً واحداً فيportals.ymlفي المشروع الأصلي؛ انظر الخطوة 5.)
الخطوة 1 — كتابة المحوّل
أنشئ server/lib/sources/<slug>.mjs. نمطان يعملان بحسب ما إذا كان المصدر يملك JSON API أو يعرض HTML فقط:
مصدر مدعوم بـ API (الأنظف — استخدمه حين يوجد endpoint بيانات مفتوح):
// server/lib/sources/example.mjs
const ENDPOINT = 'https://example.com/api/v1/vacancies';
const UA = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ...';
// v1.69.0 (P-14) — بيانات وصفية ذاتية التعريف. يكتشف السجل هذه الكتلة عند الإقلاع تلقائياً؛
// هذا ما يُسجّل المصدر (انظر الخطوة 2).
export const meta = {
value: 'example', // ← يجب أن يساوي job.source المكتوب أدناه
label: 'Example.com', // ← يظهر في قائمة الفلتر في #/scan
region: 'ru', // ← 'en' (مسح ATS) | 'ru' (dispatcher إقليمي)
configKey: 'example', // ← للروسي فقط؛ المفتاح المستخدم في portals.yml
};
export async function searchExample(query, opts = {}) {
const { onlyRemote = false, fetchImpl = fetch, signal } = opts;
const res = await fetchImpl(`${ENDPOINT}?text=${encodeURIComponent(query)}`, {
signal,
headers: { 'User-Agent': UA, Accept: 'application/json' },
});
if (!res.ok) {
const err = new Error(`Example: HTTP ${res.status}`);
err.status = res.status;
throw err;
}
const data = await res.json();
return (data.items || []).map(normalizeExample);
}
function normalizeExample(item) {
return {
id: `example-${item.id}`,
title: item.title || '',
company: item.company?.name || '',
url: item.url || '',
salary: item.salary || '',
location: item.location || '',
isRemote: !!item.remote,
workplaceType: item.remote ? 'Remote' : 'Onsite',
relocates: false,
date: item.posted_at || '',
snippet: (item.description || '').slice(0, 240),
source: 'example', // ← يجب أن يطابق قيمة `value` في السجل تماماً
};
}
مصدر يعتمد على استخراج HTML (حين لا يوجد API — راجع
getmatch.mjs و
geekjob.mjs للأمثلة الكاملة):
const BASE = 'https://example.com';
export async function searchExample(query, opts = {}) {
const { fetchImpl = fetch, signal } = opts;
const res = await fetchImpl(`${BASE}/vacancies?q=${encodeURIComponent(query)}`, {
signal,
headers: { 'User-Agent': UA, Accept: 'text/html' },
});
if (!res.ok) {
throw Object.assign(new Error(`Example: HTTP ${res.status}`), { status: res.status });
}
return parseExampleCards(await res.text());
}
export function parseExampleCards(html) {
// …استخراج البطاقات بالتعبيرات النمطية. أعِد [] عند فشل التحليل (لا تُطلق استثناء):
// 200 صحيح بدون بطاقات قابلة للتحليل هو "لا نتائج"، وليس "خطأ"،
// حتى يتمكن الماسح متعدد المصادر من المتابعة.
}
ثلاثة عقود يجب على كل محوّل الالتزام بها:
- تصدير كتلة
metaصحيحة (انظر الخطوة 2). بدونها يتخطى السجل الملف بصمت (تحذيرconsole.warnواحد عند الإقلاع) ولا يظهر المصدر أبداً. - قبول
{ onlyRemote, fetchImpl, signal }فيopts.fetchImplما يجعل المحوّلات قابلة للاختبار بدون شبكة؛signalمطلوب لنشر قطع اتصال العميل (REVIEW-B3). - إعادة السجلات بالشكل المشترك —
{ id, title, company, url, salary, location, isRemote, workplaceType, relocates, date, snippet, source }، حيث يطابقsourceقيمةmeta.value.
الخطوة 2 — إعلان meta المحوّل (التسجيل التلقائي)
هذه هي خطوة التسجيل كلها. لا تُعدّل registry.mjs. تأكد فقط من أن المحوّل يُصدِّر كتلة meta — يكتشفها السجل تلقائياً عند الإقلاع:
// في أعلى server/lib/sources/example.mjs
export const meta = {
value: 'example', // قيمة job.source وكذلك option.value في #/scan
label: 'Example.com', // تسمية العرض في القائمة المنسدلة
region: 'ru', // 'en' | 'ru'
configKey: 'example', // للروسي فقط — المفتاح في portals.yml::russian_portals.sources
};
كيف يتحقق الاكتشاف منها (ملف يفشل في أي قاعدة يُتخطى مع تحذير [sources/registry] واحد، ليظل الفرع النصفي الترحيل قابلاً للتشخيص):
value— سلسلة غير فارغة. يجب أن تطابقjob.sourceمن محوّلك.label— سلسلة غير فارغة.region—'en'أو'ru'بالضبط؛ أي قيمة أخرى تُرفض.configKey— مطلوب لـregion: 'ru'، مُتجاهَل لـ'en'.
region: 'en' ينضم إلى مسح ATS (يكتشف تلقائياً من أنماط URL في tracked_companies)؛ region: 'ru' ينضم إلى الـ dispatcher الإقليمي. الواجهة العامة (SOURCES، SOURCES_BY_REGION، RU_CONFIG_KEYS، getRegionalSources) تُعاد بناؤها من كل meta مكتشَف، مرتّبةً en أولاً ثم ru، أبجدياً حسب التسمية داخل كل منطقة — لتبقى ترتيب القائمة ثابتاً للمستخدمين.
الخطوة 3 — الربط بالـ dispatcher (للمصادر الروسية فقط)
تكتشف مصادر EN ATS تلقائياً من أنماط URL في tracked_companies — لا حاجة لربط إضافي. للمصادر الروسية، افتح
server/lib/ru-scanner.mjs، ابحث عن جدول RU_DISPATCH، وأضف صفاً:
import { searchExample } from './sources/example.mjs';
// …
const RU_DISPATCH = {
// …الموجود…
example: { label: 'example.com', search: searchExample },
};
حلقة الـ dispatcher تستدعي entry.search(query, opts) لكل مفتاح موجود في cfg.sources. لا حاجة لأي تغيير كودي آخر.
الخطوة 4 — الاختبار (محاكى، لا شبكة حقيقية)
أضف ملفاً ضمن tests/sources-<slug>.test.mjs. الشبكة الحقيقية محظورة في الاختبارات (عقد عزل CI):
import test from 'node:test';
import assert from 'node:assert/strict';
import { searchExample } from '../server/lib/sources/example.mjs';
test('searchExample normalizes one record', async () => {
const fetchImpl = async () =>
new Response(
JSON.stringify({ items: [{ id: 1, title: 'Backend Engineer' }] }),
{ status: 200, headers: { 'content-type': 'application/json' } }
);
const out = await searchExample('q', { fetchImpl });
assert.equal(out.length, 1);
assert.equal(out[0].source, 'example');
});
الخطوة 5 — التفعيل في portals.yml
ملف portals.yml في المشروع الأصلي هو إعداد مملوك للمستخدم. أضف configKey المصدر الجديد إلى المصفوفة:
russian_portals:
sources: ["hh", "habr", "trudvsem", "getmatch", "geekjob", "example"]
area: 113
per_page: 50
only_remote: false
queries:
- "Senior PHP"
- "Senior Go"
أعِد تحميل #/scan في المتصفح. تلتقط القائمة المنسدلة لفلتر المصدر الإدخال الجديد تلقائياً (مصدر حقيقة واحد عبر
GET /api/scan/sources →
registry.mjs). يشمل زر 🌐 Scan المصدرَ الجديدَ في كل مسح إقليمي.
المحوّلات المرجعية (انسخ أسلوبها للمصادر الجديدة)
| ملف المحوّل | النوع | ملاحظات |
|---|---|---|
hh.mjs |
JSON API | محوّل RU API المرجعي؛ fallback UA يراعي الموقع الجغرافي. |
trudvsem.mjs |
JSON API | بيانات حكومية روسية مفتوحة؛ بدون حاجز IP. |
habr.mjs |
HTML scrape | بوابة تقنية روسية؛ محلل بطاقات بالتعبيرات النمطية. |
getmatch.mjs |
HTML scrape | محلل دفاعي، يُعيد [] عند فشل التحليل. |
geekjob.mjs |
HTML scrape | نفس الأسلوب الدفاعي لـ GetMatch. |
greenhouse.mjs |
JSON API | محوّل EN ATS المرجعي؛ يستخدم نمط URL في tracked_companies. |
الأخطاء الشائعة
- نسيان تصدير
meta. منذ v1.69.0 كتلةmetaهي الشيء الوحيد الذي يُسجّل المصدر. بدونmeta(أو بكتلة مشوّهة) = يُتخطى الملف بصمت عند الإقلاع مع تحذير واحد:[sources/registry] <file> has no valid \export const meta` — skipped` والمصدر لا يصل إلى القائمة المنسدلة. تحقق من سجل الخادم إن لم يظهر محوّل جديد. - عدم تطابق حقل
source. السلسلة التي يكتبها محوّلك يجب أن تطابقmeta.valueتماماً. إن اختلفت، ستُظهر القائمة المنسدلة في#/scanالمصدر لكن اختياره سيُخفي كل الصفوف (لأن التحقق من التساويr.source === fs). - إطلاق استثناء عند فشل التحليل. يجب على محوّلات HTML إعادة
[]عند وجود 200 صحيح بدون بطاقات قابلة للتحليل. الإطلاق يكسر حلقة الـ dispatcher متعددة المصادر — هيكل HTML سيء واحد يُوقف كل المصادر الأخرى للاستعلام نفسه. - نسيان
fetchImpl/signal. بدونهما، لا يمكن اختبار محوّلك وحدةً دون الوصول إلى شبكة حقيقية، ولا تنتشر قطع اتصال العميل (الجلب الخلفي يستمر بعد إغلاق المستخدم للتبويب). - الثقة في
tracked_companiesللمصادر الروسية. تلك القائمة للمصادر EN ATS فقط. المحوّلات الروسية تقود نفسها منrussian_portals.queriesبدلاً من ذلك — بدون إدخالات لكل شركة.
18. الإشعارات (🔔 في الشريط العلوي)
v1.58.34 — كل toast يظهر في الزاوية اليمنى السفلية يُسجَّل أيضاً في سجل داخل الذاكرة (بحد أقصى 50 إدخالاً، يُحذف الأقدم). انقر على جرس 🔔 في الشريط العلوي لفتح درج الإشعارات المنزلق يميناً وإعادة قراءة أي شيء فاتك. السجل مرتبط بالتبويب والجلسة — إغلاق التبويب يمسحه.
يُفتح الدرج فقط عند النقر على الجرس (أو تفعيله بـ Enter / Space حين يكون في تركيز لوحة المفاتيح). لا يظهر من تلقاء نفسه. الشارة الحمراء على الجرس تعدّ الإدخالات التي لم تُشاهَد منذ آخر فتح؛ فتح الدرج يمسح الشارة.
فئات الإشعارات
| الفئة | متى تُطلَق | المؤشر البصري |
|---|---|---|
| نجاح | Saved، Copied، Refreshed، اكتمال المسح، استيراد CV، إجراءات قائمة التقديم (“Copied unchecked”، “Reset”)، حفظ الملف الشخصي، إضافة رابط Pipeline |
حدود خضراء يسرى في الدرج؛ خلفية toast خضراء |
| خطأ | فشل التحقق من الرابط (يجب أن يبدأ بـ http:// / https://، بدون رموز script/template)، أخطاء API مع لاحقة (METHOD /path · HTTP NNN)، فشل الشبكة (الخادم معطّل)، تكرارات pipeline-400، خروج doctor / verify-pipeline غير صفري |
حدود حمراء يسرى؛ خلفية toast حمراء؛ اللاحقة التقنية مطوية داخل كتلة Details <details> (U-4 / v1.58.24) |
| معلومات / تقدم | Running doctor.mjs…، Running verify-pipeline.mjs…، Refreshing…، Loading…، Generating prompt…، أسطر تقدم المسح |
حدود رمادية يسرى؛ خلفية toast افتراضية |
كل إدخال في الدرج يعرض:
- الطابع الزمني (
HH:MM:SSمُوطَّن بلغة SPA النشطة). - الرسالة (الجملة البشرية، مع حذف اللاحقة التقنية من العنوان وفق U-4).
- التفاصيل (عند وجودها — لاحقة استدعاء API
(METHOD /path · HTTP NNN)أو أي تفصيلة تقنية أخرى، بخط أحادي العرض).
ما ليس إشعاراً
- نافذة نتائج Doctor / verify-pipeline (stdout / stderr الكاملة) — تلك نافذة منبثقة وليست toast، ولا تُسجَّل في السجل.
- أسطر سجل SSE في
#/scanو#/auto— تلك تتدفق إلى جسم الصفحة، وليس إلى أنبوب toast. - حالات التحميل بمؤشر دوار فقط (تلك تستخدم
UI.withSpinnerبدون toast).
لوحة المفاتيح
- النقر أو التركيز + Enter / Space على الجرس → يفتح الدرج.
- Esc، النقر على زر × للإغلاق، أو النقر على الجرس مجدداً → يُغلق الدرج؛ يعود التركيز إلى الجرس.
- Tab أثناء فتح الدرج → يتنقل عبر زر الإغلاق وأي تفاصيل قابلة للتركيز بداخله؛ الدرج
aria-modal="false"لذا Tab لا يُقيّد (يمكنك الوصول إلى بقية الصفحة).
19. ترجمة التطبيق إلى لغتك
تشحن الواجهة بـ 9 لغات (English، Español، Français، Português، 한국어、日本語、Русский、简体中文、繁體中文). كل تسمية على الشاشة تأتي من قاموس ترجمة، ويمكنك إضافة لغة أو تصحيحها دون لمس منطق التطبيق.
مكان الترجمات. منذ v1.60.0 كل لغة لها ملفها الخاص ضمن public/js/lib/locales/ — i18n-dict.en.js، i18n-dict.es.js، i18n-dict.ru.js، وهكذا — قائمة بسيطة من أزواج 'key': 'text'. ملف i18n-dict.aliases.js المشترك يسمح للمفاتيح التي يجب أن تقرأ بالطريقة ذاتها دائماً (تسمية الشريط الجانبي وعنوان صفحتها) بالإشارة إلى ترجمة واحدة. يدمجها i18n-dict.js كلها عند تحميل الصفحة؛ لا تُعدّله أبداً.
تصحيح أو إضافة عبارة. افتح ملف لغتك، ابحث عن المفتاح (مثل 'nav.scan') وعدّل النص. لإضافة تسمية جديدة كلياً، أضف المفتاح نفسه إلى جميع الـ 8 ملفات اللغوية بالقيمة المترجمة، ثم استشِر إليه في الصفحة عبر t('your.key'). شغّل npm test — يفشل إن غابت أي لغة عن المفتاح، حتى لا يشحن شيء نصف المترجَم.
إضافة لغة كاملة جديدة. انسخ i18n-dict.en.js إلى i18n-dict.<code>.js، ترجم كل قيمة، ثم سجّل الكود في i18n.js (قائمة اللغات + الاكتشاف التلقائي للمتصفح)، وفي مجمّع i18n-dict.js، وأضف سطر <script> في index.html. القائمة الاسترشادية الكاملة — بما فيها لقطة الاختبار وملفات المساعدة و README المرافقة — موجودة في docs/LOCALIZATION.md.
جيّد أن تعلم. مُبدِّل اللغة موجود في تذييل الشريط الجانبي؛ اختيارك يُحفظ لكل متصفح. رسائل تشخيص الخادم تبقى بالإنجليزية عن قصد (حتى تُقرأ السجلات باتساق) — الواجهة على الشاشة فقط هي المترجَمة.
20. إحصاءات حسب الأدوار المستهدفة (#/stats)
صفحة Analytics ← إحصاءات الأدوار المستهدفة تحوّل البيانات الشحيحة التي تجمعها عمليات المسح لديك بالفعل إلى صورة للسوق عن الأدوار التي تستهدفها فعلاً: أعداد الوظائف الشاغرة ومستويات الرواتب حسب البلد، إضافةً إلى اتجاه يمكنك تتبّعه عبر الزمن. لا شيء مُختلَق: فهي تجمّع فقط ما وجدته أدوات المسح، وتكون صادقة بشأن مدى ضآلة العينة.
من أين تأتي الأرقام
- تُقرأ الأدوار المستهدفة من ملفك الشخصي (
config/profile.yml← target roles) — ولا تُكتَب في الكود إطلاقاً. عيّنها أولاً في#/profile؛ فبدون أدوار تعرض الصفحة رسالة «عيّن أدوارك المستهدفة» بدلاً من رسوم بيانية فارغة. - تأتي الإعلانات من آخر عملية مسح لديك (شغّل واحدة أولاً في
#/scan). يُربَط موقع كل وظيفة ببلد (بالكاشف نفسه المستخدَم في مرشّح البلد بالمسح)، ويُحلَّل نصّ الراتب ويُطبَّع إلى USD عبر جدول تقريبي لأسعار الصرف. - يُجمَّع كل شيء في متصفّحك — فلا تغادر أي بيانات جهازك، والشيء الوحيد الذي تكتبه هذه الصفحة على الإطلاق هو لقطة تحفظها أنت صراحةً.
قراءة الرسوم البيانية
- الوظائف الشاغرة حسب البلد — كم عدد الإعلانات المطابقة في كل بلد. استخدم مرشّحَي الدور والبلد في الأعلى للتضييق إلى دور مستهدف واحد أو بلد واحد.
- الراتب الوسيط حسب البلد (USD) — الراتب المتوسط المُحلَّل لكل بلد. تُحتسب فقط الإعلانات ذات الراتب القابل للتحليل؛ ويظهر حجم العينة بجانب الرسم، وتُحوَّل المبالغ بأسعار تقريبية، فاقرأها بوصفها استرشادية لا دقيقة. يُسقَط رمز
¥المنفرد (الملتبس بين الين الياباني واليوان الصيني) بدلاً من تخمينه، تفادياً لتشويه كبير في FX. - عندما لا تحتوي عملية المسح الحالية على رواتب قابلة للتحليل، يذكر رسم الرواتب ذلك بدلاً من اختلاق أرقام.
حفظ اللقطات وتتبّع الاتجاه
- انقر حفظ لقطة لإلحاق المُجمَّع الحالي بـ
data/role-stats.jsonl. تُختَم كل لقطة بطابع زمني على الخادم؛ واللقطات هي الشيء الوحيد الذي تكتبه هذه الصفحة، وهي لا تمسّ سيرتك الذاتية أو ملفك الشخصي أبداً. - يرسم مخطط الاتجاه أعداد الوظائف الشاغرة عبر لقطاتك المحفوظة — احفظ واحدة دورياً (مثلاً بعد كل مسح أسبوعي) لتراقب كيف يتحرّك السوق الخاص بأدوارك المستهدفة عبر الزمن.
21. صفحتك المزدوجة (two-pager) — ملاءمة السوق للمرشّح (#/two-pager)
يسأل معظم career-ops-ui: “هل تُطابق هذه الوظيفة سيرتي الذاتية؟”. تُجيب الصفحة المزدوجة (two-pager) عن النصف الآخر: “هل تُطابق هذه الوظيفة ما أريده فعلاً؟”. وهي مصمّمة على غرار “Mnookin two-pager” من كتاب Never Search Alone — بيان قصير بصيغة المتكلّم عمّا يمنحك الطاقة، وما تشترطه، وما لن تقبله. افتحها من الإعداد → Two-pager 🎯.
التعبئة التلقائية بالذكاء الاصطناعي + التصدير (v1.100). يملأ «✨ مساعد التعبئة بالذكاء الاصطناعي» الآن جميع الحقول مباشرةً من سيرتك (راجع ثم احفظ)؛ و**👁 معاينة وتصدير** يعرض الوثيقة ويصدّرها إلى Markdown أو PDF أو DOCX.
ما الذي تملؤه
- من أنا — بضع جُمل بصيغة المتكلّم عن سجلّك المهني ونوع الدور الذي تزدهر فيه.
- البيئة المستهدفة — حجم الشركة ومرحلتها والثقافة التي تريدها.
- خمس قوائم رقاقات (chip-lists) — اكتب واضغط Enter (أو الفاصلة) لإضافة كل عنصر، وانقر × لإزالته:
- ما أحبّه — ما يمنحك الطاقة (العمل عن بُعد، الملكية، المشاريع الجديدة، التوجيه…).
- متطلبات لا بدّ منها — شروط صارمة (حدّ أدنى للأجر، بلد ما، حزمة تقنية…).
- ما أكرهه — ما يستنزفك (المناوبات، الاجتماعات التي لا تنتهي، الأنظمة القديمة فقط…).
- عوامل حاسمة (deal-breakers) — رفض مطلق (العمل الحضوري فقط، لا كفالة، أقلّ من مبلغ ما…).
- غير قابلة للتفاوض — حدود (الموقع، العمل عن بُعد، حدّ أدنى للأجر…).
انقر حفظ الصفحة المزدوجة لحفظها. تُكتَب في طبقة المستخدم للمشروع الأصلي career-ops في config/two-pager.yml، لذا — مثل سيرتك الذاتية وملفك الشخصي — لا يُعاد الكتابة فوقها أبداً عند تحديث النظام.
مساعد التعبئة بالذكاء الاصطناعي
لست متأكداً من الصياغة؟ انقر ✨ AI fill assistant. يبني مطالبة (prompt) جاهزة للتشغيل (بصيغة Mnookin، مع تضمين سيرتك الذاتية وملفك الشخصي) ويعرضها في حوار. شغّل تلك المطالبة في أي نموذج LLM، ثم ألصق حقول YAML الناتجة مرةً أخرى في النموذج. لا يستخدم المساعد سوى سيرتك الذاتية وملفك الشخصي — فهو لا يختلق حقائق عنك أبداً، ولا يُجرى أي طلب API مباشر من هذا الزر.
درجة الملاءمة لما تريده (fit-to-what-you-want)
بمجرد حفظ صفحة مزدوجة، يحصل كل إعلان على #/scan على شارة صغيرة ◎ N (0–100). تقارن نوع العمل لكل وظيفة (عن بُعد/هجين/حضوري)، والبلد، والحدّ الأدنى للأجر، والانتقال مع صفحتك المزدوجة — الشارة الخضراء تعني ملاءمة قوية، والحمراء تعني أن عاملاً حاسماً قد تفعّل. مرّر المؤشّر فوقها للتفاصيل (✓ ما طابق، ✗ ما خالفه عامل حاسم).
وهي صادقة عن قصد: عندما لا يقدّم الإعلان أي إشارة قابلة للمطابقة (مثلاً عندما تكون تفضيلاتك كلها نصاً حرّاً لا يمكن لصفّ المسح تأكيده)، لا تظهر أي شارة على الإطلاق — فالنظام لا يختلق رقماً أبداً. ومخالفة العامل الحاسم الصارمة تزن أثقل من كره بسيط للشيء نفسه. وإلى جانب الشارة، تُضمَّن صفحتك المزدوجة المحفوظة في كل تقييم LLM، بحيث تُشكّل تفضيلاتك المُعلَنة الحكم المكتوب أيضاً، لا مجرد مطابقة السيرة الذاتية مقابل الوصف الوظيفي.
22. مقابلة تجريبية (#/mock-interview)
قراءة مواد التحضير للمقابلة شيء؛ وقول الإجابات بصوت مسموع شيء آخر. تُجري صفحة المقابلة التجريبية (افتحها من Interview prep → Mock interview 🎤 في الشريط الجانبي) بروفة دوراً بدور مقابل دور محدّد، مرتكزةً على سيرتك الذاتية وملفك الشخصي وصفحتك المزدوجة وبنك القصص الخاص بك. إنها ليست قائمة أسئلة جاهزة — فالمُحاوِر يتفاعل مع ما تقوله فعلاً.
بدء جلسة
- أدخل الدور المستهدف (وإن شئت الشركة). وإن كان لديك الوصف الوظيفي فألصقه أيضاً — تصبح الأسئلة أكثر حدّة بشكل ملحوظ.
- انقر Start interview. يفتتح المُحاوِر بسؤال واحد مركّز مصمّم خصّيصاً للدور ولخلفيتك.
- اكتب إجابتك وانقر Send answer. كرّر ذلك بقدر ما تشاء — إنه محادثة، وليس اختباراً ثابتاً.
ماذا يمنحك كل دور
بعد كل إجابة، يردّ المُحاوِر بثلاثة أجزاء:
- ملاحظات — ما نجح (نقاط القوة) وما كان ناقصاً، مصاغةً بمنطق STAR+R (Situation، Task، Action، Result، Reflection). يُسمّي البُعد المحدّد الذي تخطّيته.
- درجة —
N/5سريعة مع مبرّر من سطر واحد، لتلمس تقدّمك عبر الجلسة. - السؤال التالي — سؤال متابعة يستقصي عمداً أضعف جزء في إجابتك الأخيرة.
كل شيء مرتكز على موادّك الحقيقية: cv.md وconfig/profile.yml وconfig/two-pager.yml وبنك قصص STAR+R الخاص بك (interview-prep/story-bank.md) كلها مضمَّنة داخل المطالبة. سيضغط المُحاوِر على الثغرات الحقيقية لكنه لا يختلق أبداً خبرةً لا تملكها. وإن لم يُضبَط مفتاح LLM، تسلّمك الصفحة مطالبةً جاهزة للتشغيل لتلصقها في أي مساعد — وهو نفس البديل الأمين المستخدَم في مواضع أخرى من التطبيق.
حفظ الجلسات ومراجعتها
انقر Save transcript للاحتفاظ ببروفة منتهية. تُكتَب في طبقة المستخدم للمشروع الأصلي في interview-prep/mock-{company}-{role}-{date}.md، فتعيش إلى جانب باقي ملاحظات التحضير للمقابلة ولا يُعاد الكتابة فوقها بتحديثات النظام. تتيح لك قائمة Saved sessions أسفل الصفحة إعادة فتح أي نصّ محفوظ أو حذفه. استخدم New interview لتبدأ من جديد بدور مختلف.
23. التواصل المهني والبحث المعمّق عن الشركات (#/networking)
التقديم عبر الباب الأمامي ليس سوى نصف اللعبة — أمّا النصف الآخر فهو أن تعرف أحدهم، أو على الأقل أن تعرف بمن تتصل وماذا تقول. صفحة Networking (افتحها من البحث المعمّق ← Networking 🤝 في الشريط الجانبي) تحوّل الشركة إلى خطة ملموسة للحصول على مقابلة، مستندة إلى سيرتك الذاتية وملفّك الشخصي و two-pager الخاص بك.
بناء خطة
- أدخل شركة (إلزامي)، واختيارياً منصباً والوصف الوظيفي. الوصف الوظيفي يشحذ خطّافات «لماذا أنا مناسب».
- انقر بناء الخطة. مع مفتاح LLM يعمل مباشرةً ويعرض الخطة داخل الصفحة؛ ومن دون مفتاح يسلّمك مطالبة جاهزة للصق في أي مساعد (نفس البديل الأمين المستخدَم في كامل التطبيق — لا شيء يُختلق).
ما تحتويه الخطة
تعود الخطة في أربعة أقسام:
- ملف الشركة — موجز مكثّف عمّا تفعله الشركة، وإشارات حديثة تستحق الاقتباس، واثنان أو ثلاثة من خطّافات «لماذا أنا مناسب» مستخلَصة من خلفيتك الحقيقية.
- بمن تتصل — من ثلاثة إلى خمسة أشخاص مستهدفين (مدير التوظيف للفريق، أخصائي توظيف داخلي، مهندس أول في الفريق، معرفة دافئة أو صلة عبر الخريجين) مع سلسلة بحث في LinkedIn ملموسة للعثور على كل واحد منهم. لا يختلق أبداً أسماءً حقيقية — بل يخبرك كيف تجد الأشخاص المناسبين.
- أدفأ مسار للتعارف — الطريق الدافئ الأكثر واقعيةً للدخول بالنسبة لخلفيتك أنت: صاحب عمل أو مدرسة أو مجتمع مشترك؛ صلة من الدرجة الثانية؛ أو رسالة باردة عالية الإشارة عندما تكون هذه حقاً الخيار الأفضل.
- مسوّدات التواصل — رسائل قصيرة ومحدَّدة (من ثلاث إلى خمس جُمل، بلا حشو) لأهم أشخاصك المستهدفين، مستندة إلى نقاط إثباتك الحقيقية كي لا تبدو عامّة.
حفظ الخطط والعودة إليها
انقر حفظ الخطة للاحتفاظ بواحدة. تُكتَب في طبقة المستخدم للمشروع الأصل في networking/net-{company}-{role}-{date}.md — ملفّك الخاص، لا تُستبدَل أبداً بتحديثات النظام. تتيح لك قائمة الخطط المحفوظة في أسفل الصفحة إعادة فتح أي خطة أو حذفها. ولمّا كانت المسوّدات والأشخاص مستندة فقط إلى موادّك الحقيقية، فتعامل معها كمسوّدة أولى قوية للتخصيص — لا كنصّ تُرسله على العمياء.
24. استوديو السيرة الذاتية (#/cv-studio)
أضِف إلى السيرة (v1.117.0). بطاقة جديدة تحوّل مشروعًا أو منشورًا أو صفحة أعمال (رابطًا أو نصًا ملصوقًا) إلى نقاط جاهزة لأنظمة ATS مبنية فقط على ذلك المصدر — تُحذف المقاييس أو أصحاب العمل أو التواريخ غير الموجودة في المصدر ولا تُختلق أبدًا. تراجع الاقتراحات وتلصق ما تقبله بنفسك في محرر السيرة؛ لا يُكتب شيء تلقائيًا، وتمر الروابط عبر نفس مدقق SSRF الآمن الخاص بخط الأنابيب.
صفحة #/cv هي المكان الذي تكتب فيه سيرتك الذاتية؛ أما استوديو السيرة الذاتية (افتحه من Setup ← CV Studio 🎨 في الشريط الجانبي) فهو المكان الذي تصقلها فيه. يمنح ملف cv.md الخاص بك ثلاث أدوات صادقة، اثنتان منها لا تغادران متصفحك أبدًا.
التكييف مع وظيفة (v1.101). الصق وصف وظيفة لينتج CV Studio سيرة ذاتية مكيّفة وخطاب تقديم مطابق، بعد تمريرهما عبر بوابة قائمة تحقق بمستوى مسؤول التوظيف (الأخطاء تحجب، والتحذيرات تنصح)، اعتماداً على موادك فقط.
تشخيص السيرة الذاتية
في اللحظة التي تفتح فيها الصفحة، تمنح سيرتك الذاتية درجة من 100 وتسرد النتائج لكل فحص، كل واحدة مصحوبة بشرح موجز حتى تقرر أنت ما الذي تغيّره (فهي لا تعيد الكتابة بصمت أبدًا):
- الطول — هل السيرة الذاتية ضمن نطاق صحي من صفحة إلى صفحتين؟
- الأثر القابل للقياس — ما نسبة نقاطك التي تتضمن رقمًا أو مقياسًا حقيقيًا؟ يبحث المسؤولون عن التوظيف عنها أثناء التصفح السريع.
- أفعال حركة قوية — تُعلِّم على الصياغات الضعيفة مثل «مسؤول عن» أو «ساعدت في».
- الكلمات الرنانة — تُعلِّم على العبارات المبتذلة الفارغة («موجَّه نحو النتائج»، «لاعب فريق»).
- الأقسام الأساسية — تتحقق من وجود الملخص والخبرة والتعليم والمهارات.
- معلومات الاتصال — تتأكد من وجود بريد إلكتروني.
يعمل هذا كله بالكامل داخل متصفحك دون أي LLM — الأرقام حتمية ولا يُختلق أي شيء.
قناع الخصوصية
قبل مشاركة سيرتك الذاتية كعينة كتابة أو لقطة شاشة، يُخفي قناع الخصوصية البيانات المُعرِّفة للهوية الشخصية: البريد الإلكتروني والهاتف والروابط/المعرّفات وعنوان الشارع، إضافةً إلى اسمك ← الأحرف الأولى إذا فعّلت ذلك وأدخلته. بدّل كل فئة، وانسخ النسخة المُقنَّعة، وشاركها بأمان. يحدث ذلك بالكامل داخل المتصفح، ويُبلِّغ بالضبط عن عدد العناصر التي أخفاها، ولا يخزّن الأصل أو يُرسله أبدًا.
اجعله بشريًا (مطابقة الصوت)
الصق سطرًا أو فقرة جامدة — من نوع الصياغة العامة للذكاء الاصطناعي التي تُقرأ كنص جاهز — واجعله بشريًا يعيد كتابته بصوتك أنت. تستند إعادة الكتابة على جانب الخادم إلى ملف voice-dna.md الخاص بك (كيف تُقرأ كتابتك) وإلى writing-samples/ (نثرك الحقيقي). القاعدة الصارمة: يجوز له إعادة الترتيب والاختصار وإعادة ضبط الصوت، لكنه لن يُدخِل أبدًا حقيقة أو مقياسًا أو إنجازًا ليس موجودًا أصلًا في النص الذي ألصقته. مع مفتاح LLM يعيد الكتابة مباشرةً؛ وبدون مفتاح يسلّمك مُوجَّهًا جاهزًا للصقه في أي مساعد. بعد ذلك حرِّر سيرتك الذاتية في صفحة #/cv كالمعتاد — استوديو السيرة الذاتية يقترح، وأنت تقرر.
25. الذاكرة (#/memory)
كل صفحة أخرى تبدأ من جديد في كل مرة. الذاكرة (افتحها من الإعداد ← الذاكرة 🧠 في الشريط الجانبي) هي المكان الوحيد الذي تخبر فيه المساعد بشيء مرة واحدة فيبقى راسخًا. تحتوي على ملاحظة قصيرة قابلة للتعديل من نوع «تذكّر هذا عنّي» تُدرَج في كل طلب إلى الذكاء الاصطناعي.
ما فائدتها
استخدمها للتفضيلات الدائمة وأسلوب العمل، على سبيل المثال:
- أنواع الأدوار والشركات التي تستهدفها (وتلك التي لا تريد رؤيتها أبدًا).
- كيف تحب أن تُكتب الإجابات — موجزة أم مفصّلة، بنبرة خبير، دون حشو.
- القيود الصارمة الجديرة بالتكرار — عن بُعد فقط، حدّ أدنى للأجر، دون مناوبات طارئة.
اقصرها على التفضيلات والتوجيه. إنها ليست المكان المناسب للحقائق المتعلقة بخبرتك — فمهاراتك وأصحاب عملك وإنجازاتك تعيش في سيرتك الذاتية وملفك الشخصي وملخصك المكوّن من صفحتين، وهي تظل المصادر الوحيدة لأي شيء يظهر في سيرك الذاتية وخطابات التقديم. ملاحظة الذاكرة تشكّل كيف يعمل المساعد معك، لا ما يزعمه عنك أبدًا.
كيف تصل إلى كل شيء
عندما تنقر على حفظ الذاكرة، تُكتب الملاحظة في طبقة المستخدم في مشروعك الأصل عند config/memory.md وتُدمَج في سياق المشروع المشترك. هذا يعني أنها تنتقل تلقائيًا مع كل طلب إلى الذكاء الاصطناعي — التقييمات، والمقابلات التجريبية، وخطط التواصل، وإعادة الكتابة في CV Studio — وعبر كل مزوّد قمت بإعداده. اكتبها مرة واحدة؛ لست مضطرًا لتكرار نفسك في كل صفحة. مثل بقية ملفات طبقة المستخدم لديك، لا يُكتب فوقها أبدًا عند تحديث النظام، ولا تغادر جهازك إلا داخل مطالبات LLM التي تختار تشغيلها.
اقترح من بياناتي
لست متأكدًا ماذا تكتب؟ ✨ اقترح من بياناتي يقرأ متتبّع طلباتك ويصوغ مجموعة من النقاط السلوكية — الأنماط في ما تسعى إليه وتقبله وترفضه. شغّل المطالبة التي يمنحها لك في أي LLM، وراجع الاقتراحات، والصق نسخة معدّلة في الملاحظة. إنه يستمدّ فقط من متتبّعك الخاص ولا يختلق حقائق أبدًا؛ وأنت تراجع دائمًا قبل حفظ أي شيء.
26. الإحصاءات (#/stats)
تبويب أنماط الرفض (v1.117.0). تبويب رابع يشغّل analyze-patterns.mjs من الأصل (قراءة فقط) ويعرض توزيع النتائج وتوصيات قابلة للتنفيذ ومعدل التقدّم لكل مزوّد ATS (إشارة «الأحادية الخوارزمية» — Bommasani et al., FAccT 2026). المزوّدون دون الحد الأدنى للعينة يحملون نجمة؛ ودون المشروع الأصل يخبر التبويب بذلك بصدق.
تجمع صفحة الإحصاءات ثلاث عروض ضمن قسم واحد: تقرير سوق مُولَّد بالذكاء الاصطناعي، وتحليلات لِمسار طلباتك الخاص، واتجاه أعداد الوظائف الشاغرة لأدوارك المستهدفة انطلاقًا من عمليات المسح لديك. بدّل بينها عبر علامات التبويب في الأعلى.
تقرير السوق
تطلب علامة التبويب تقرير السوق من النموذج تحليلًا للأجور وسوق العمل لِـأدوارك المستهدفة — فهي تقرأ سيرتك الذاتية وملفك الشخصي لتعرف أي الأدوار وأي مستوى أقدمية يجب تغطيته. اكتب المنطقة / السوق (على سبيل المثال Russia أو EU-remote أو US أو Germany)، واختر العملة، وانقر على توليد تقرير السوق. تحصل على تقرير منظّم يتضمّن ملخصًا تنفيذيًا، والأجور حسب الدرجة (الوسيط إضافةً إلى P10/P25/P75/P90)، وكبار أصحاب العمل، وجدولًا بالمهارات المطلوبة، وتكرار المزايا، وتوزيع المكتب/الهجين/عن بُعد، واتجاهات على مدى 12-24 شهرًا بما في ذلك تأثير الذكاء الاصطناعي، وإرشادات التفاوض. كل رقم هو تقدير توجيهي مستمَد من معرفة تدريب النموذج — وليس بيانات مستخرجة أو حيّة — والتقرير يذكر ذلك؛ فتعامل مع الأرقام كنطاقات لا كاقتباسات. من دون ضبط مفتاح API تحصل على مطالبة للنسخ واللصق بدلًا من تقرير ملفَّق. استخدم تنزيل .md أو حفظ بصيغة PDF أو نسخ لإخراج التقرير من التطبيق.
مساري
ترسم علامة التبويب مساري رسمًا بيانيًا لِمتتبّع طلباتك الخاص — لا شيء خارجي. تُظهر عدد الأدوار التي تابعتها، وتوزيع درجاتك، وقُمع الحالات، وأبرز الشركات والأدوار لديك، والطلبات عبر الزمن، ومعدلات التحويل (ما نسبة الطلبات التي تبلغ حالة تقدّمتُ وتمّ الرد ومقابلة وعرض). إنها المرآة الصادقة لبحثك: فهي لا تعكس إلا ما هو موجود بالفعل في data/applications.md.
اتجاه الأدوار المستهدفة
علامة التبويب اتجاه الأدوار المستهدفة هي العرض الأصلي: أعداد الوظائف الشاغرة والأجر الوسيط حسب البلد لأدوارك المستهدفة، مُجمَّعة من آخر عملية مسح لديك، مع محدِّد للعملة ونظرة عامة على الإعلانات حسب الدور المستهدف. تسجّل حفظ لقطة التجميع الحالي كي تتمكن من متابعة كيف تتحرك أعداد الوظائف الشاغرة عبر الزمن، وخط الاتجاه يقرأ تلك اللقطات مجددًا. البيانات المتناثرة أمر متوقّع وتُوسَم بأنها استرشادية — ولا تُحشى أبدًا بأرقام مختلَقة.
الإجمالي والتعويضات
يمرّر تبويب الإجمالي (v1.118.0) سكربتين من المشروع الأب بلا تكلفة توكنات وللقراءة فقط: stats.mjs — ملخص المتتبِّع الإجمالي، معدلات القمع التراكمية (الرد / المقابلة / العرض)، إجماليات الماسح وتغطية البوابات — وsalary-gap.mjs — التعويض المرغوب مقابل المعلن مقابل الفعلي لكل طلب، مجمّعًا من Machine Summary في التقارير ومن data/salary-observations.tsv. تُوسم العينات الصغيرة بأنها استرشادية؛ ومن دون المشروع الأب يعرض التبويب ملاحظة صادقة.
27. الخطة المهنية (#/career-plan)
تحوّل صفحة الخطة المهنية سيرتك الذاتية وملفك الشخصي إلى خطة تطوير محددة ومخصّصة — من النوع الذي قد تبنيه مع مدرّب مهني، لكنها مولّدة من موادك الخاصة وهي ملكك لتحريرها.
توليد خطة
اختر أفقًا (6 أو 12 أو 24 شهرًا)، واكتب اختياريًا تركيزًا (على سبيل المثال «الانتقال إلى الإدارة» أو «العمل عن بُعد» أو «التحوّل إلى Go»)، ثم انقر على توليد الخطة. يقرأ النموذج سيرتك الذاتية وملفك الشخصي وملخّصك المكوّن من صفحتين وملاحظة الذاكرة (عبر سياق المشروع المشترك) ويكتب خطة منظّمة: لقطة صادقة لنقطة الانطلاق، وتحليل SWOT لنقاط القوة ومجالات النمو، وأهدافًا معبّرًا عنها بصيغة SMART / OKR / WOOP، ومسارات مهنية بديلة مع مقايضاتها، وخطة للمهارات الصلبة والناعمة، وخارطة طريق شهرًا بشهر للأفق الذي اخترته، وكيفية تتبّع التقدّم، والعثرات المحتملة، وخطوات الدعم. كل توصية متجذّرة فيما تُظهره موادك فعلًا — فهي تخطّط إلى الأمام ولا تختلق أبدًا وقائع عن تاريخك. وفي غياب مفتاح API معيّن، تحصل بدلًا من ذلك على مطالبة (prompt) للنسخ واللصق.
التحرير والحفظ
تظهر الخطة في منطقة نصية قابلة للتحرير — عدّل أي شيء، ثم انقر على حفظ الخطة. تُكتب في طبقة المستخدم لمشروعك الأصل في config/career-plan.md، فتبقى بعد تحديثات النظام ولا تُرسَل إلا داخل مطالبات LLM التي تختار تشغيلها. تعرض معاينة نصّ Markdown الخاص بك بحيث يمكنك قراءته منسّقًا قبل الحفظ.
التصدير
استخدم تنزيل .md أو حفظ كـ PDF أو نسخ لإخراج الخطة من التطبيق — وهي أدوات التصدير نفسها المستخدَمة عبر تقارير الذكاء الاصطناعي في التطبيق. يمر ملف PDF عبر مولّد PDF المضمّن الحالي؛ أما Markdown فهو تنزيل مباشر.
28. التوجيه المهني (#/orientation)
تجيب صفحة التوجيه المهني عن سؤال «أي الاتجاهات تناسبني فعلاً؟» — وهي قراءة من النوع الذي قد تحصل عليه من اختبار مهني، لكنها مُستنتَجة من سيرتك الذاتية وملفك الشخصي بدلاً من استبيان.
ماذا تُنتج
انقر إنشاء الملف، فيقرأ النموذج سيرتك الذاتية وملفك الشخصي وورقتك المكوّنة من صفحتين وملاحظتك، ويكتب ملف توجيه مهني: أفضل المسارات المهنية المطابقة لك (أيّ من الأنماط الثمانية — الوظيفي، والإداري، والمُتواصِل، والأخصائي، والمُحلِّل، والمُبتكِر، والمدير، وريادي الأعمال — يناسبك أكثر، مع أدلّة من سيرتك الذاتية)، وميل نحو نوع مهني، ومجموعة من الأدوار الموصى بها، ونقاط قوتك المهنية المرتبطة بما تُظهره سيرتك الذاتية، ونزعات أسلوب العمل («كيف تُقرأ سيرتك الذاتية» على بضعة محاور)، وتوصيات للتطوير لتوسيع ملاءمتك.
كيف يُنشأ
إنه تأمّل بالذكاء الاصطناعي لكيفية قراءة سيرتك الذاتية — وليس اختباراً نفسياً. المُوجِّه مبني بالكامل على موادّك أنت: لا يختلق الإنجازات ولا يبلّغ أبداً عن درجات اختبار رقمية كأنها مُقاسة. وإذا لم يكن هناك مفتاح API مُعدّ، فستحصل على مُوجِّه للنسخ واللصق لتشغيله في أي نموذج لغوي كبير بدلاً من ملف مباشر. لا يُكتب شيء على القرص — يُنشأ الملف من جديد في كل مرة.
التصدير
استخدم تنزيل .md أو حفظ كـ PDF أو نسخ للاحتفاظ بالملف — وهي نفس عناصر التصدير المستخدَمة عبر تقارير الذكاء الاصطناعي في التطبيق. يمرّ ملف PDF عبر مُولِّد PDF المُضمَّن الحالي، أما Markdown فهو تنزيل مباشر.