SSD Nodes Learn Hosting plans →
الأدلة Matt Connorبقلم Matt Connor · آخر تحديث في 2026-08-21

استضافة Deer Workflow على VPS وتشغيله عبر systemd

ثبّت Deer Workflow بإصدار محدد على Ubuntu VPS باستخدام Bun، وشغّل graph واحداً بلا واجهة عبر systemd، مع سجل أحداث قابل للبحث عند فشل التشغيل.

ما الذي ستبنيه

Deer Workflow هو runtime يعتمد على الكود لإنشاء agent graphs: يوجد تدفق التحكم في ملف TypeScript يمكنك مراجعته، بينما ينفّذ coding agent الأجزاء التي تتطلب حكماً فقط. يثبّت هذا الدليل البرنامج على Ubuntu VPS واحد، ويشغّل graph مثالياً في وضع headless ضمن systemd، ويكتب تدفق الأحداث القابل للقراءة آلياً في ملف سجل يمكنك البحث فيه عندما يفشل التشغيل في الثالثة صباحاً.

المكوّنات بسيطة. يشغّل Bun واجهة CLI. وينفّذ coding agent CLI واحد، سواء Codex أو Claude Code، مهام النموذج. وتحتوي حزمة npm واحدة مثبتة الإصدار على runtime. ويحتوي ملف TypeScript واحد على graph الخاص بك. وتشغّل خدمة systemd ومؤقّت systemd هذا الملف وفق جدول زمني. يغطي معظم هذا الدليل الأجزاء التي تتعطل فعلياً: قيمة PATH داخل وحدة systemd، وبيانات اعتماد agent في جلسة لا تحتوي على login shell، وتثبيت إصدار dependency نُشر لأول مرة في July 2026.

المنشئ المرئي أم البرمجة أم مجرد توجيه الوكيل

يختار مستخدم الاستضافة الذاتية لأتمتة العمل باستخدام نموذج واحداً من ثلاثة أشكال، ولكل شكل أسباب فشل مختلفة.

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

توجيه الوكيل مباشرة هو الشكل الثاني. تصف المهمة كاملةً في فقرة، وتدع النموذج يقرر ترتيب الخطوات وعدد مرات إعادة المحاولة ومتى يتوقف. ينجح ذلك إلى أن يقرر النموذج التصرف بطريقة مختلفة. لا يوجد تصحيح، لأنه لا يوجد أثر محفوظ؛ فقد عاشت الخطة داخل المحادثة، ثم اختفت المحادثة.

التنسيق باستخدام الشيفرة هو الشكل الثالث. يكون ترتيب الخطوات والتوزيع المتوازي وإعادة المحاولة ومعالجة الأخطاء شيفرة TypeScript عادية محفوظة في git. ويُستدعى النموذج في المواضع التي تتطلب حكماً فقط، وليس في أي موضع آخر. لكن كلفة ذلك أن على شخص ما كتابة هذه الشيفرة وصيانتها، كما أن الزميل الذي لا يكتب TypeScript لا يستطيع تعديلها.

ما الذي يقدّمه تشغيل الرسم البياني، وما تكلفته

  • تدفّق تحكم يمكنك مراجعته. الرسم البياني ملف. يظهر تغيير سياسة إعادة المحاولة في طلب السحب على شكل 3 أسطر متغيّرة، لا على شكل مربع نُقل.
  • معالجة الأعطال في نظام التحكم بالإصدارات. ما يحدث عند فشل الخطوة الرابعة مكتوب ومختبر وموسوم مع بقية بنيتك التحتية.
  • وكيل يمكنك تبديله. يوفّر runtime محولات لـCodex وClaude Code وPi. وتغيير الوكيل الذي ينفّذ خطوة ما يتطلب استيراداً واحداً.
  • تنفيذ يمكنك مراقبته. تخرج المراحل والأحداث من runtime في صورة بيانات منظّمة، لذلك يترك التشغيل دون واجهة سجلاً يمكنك الاستعلام منه.

تُسمّى الممارسة العامة، أي تصميم الحلقة التي يعمل النموذج داخلها بدلاً من تحسين prompt واحد، هندسة الحلقة، وruntime الخاص بالرسم البياني طريقة عملية واحدة لتنفيذ ذلك. تكمن التكلفة في الإعداد: تثبيت runtime، ومصادقة CLI الخاص بالوكيل، وعدم وجود واجهة لغير المبرمجين، ومتابعة dependency حديثة ينبغي مراقبتها.

المشروع جديد، لذا ثبّت الإصدار

Deer Workflow مرخّص بموجب MIT وهو مشروع جديد. في 19 August 2026، يحتوي المستودع على 47 عملية إيداع على main. يحتفظ npm بثلاثة إصدارات منشورة: 0.0.1 و0.1.0 في 26 July 2026، ثم 0.2.0 في 27 July 2026. توجد وسم git لكل إصدار، وتجد في سجل التغييرات ما تغيّر بينها. يزيل قسم Unreleased فيه بالفعل الأمر deer-workflow agent، ولذلك لم يعد main وأحدث إصدار منشور يقدّمان واجهة CLI نفسها.

هذا ليس سبباً لتجنب المشروع. بل سبب لتثبيت إصدار واحد محدد ومعرفة الإصدار الذي ثبّتَّه.

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

ثبّت Bun وبيئة تشغيل وكيل واحدة

تُنفَّذ جميع الخطوات أدناه كمستخدم عادي لديه صلاحيات sudo. لا تُنفّذها كمستخدم root. تحفظ واجهات CLI الخاصة بالوكلاء بيانات الاعتماد ضمن الدليل المنزلي للمستخدم الذي سجّل الدخول، ولذلك يجب أن تعمل وحدة systemd لاحقاً بصلاحيات المستخدم نفسه حتى تتمكن من العثور عليها.

sudo apt update
sudo apt install -y curl unzip jq git nodejs npm
curl -fsSL https://bun.com/install | bash

يفك مثبت Bun أرشيف zip، لذلك يجب توفر unzip أولاً. يضيف المثبت أسطر PATH إلى ملف تعريف shell، لكن shell الحالي قرأ هذا الملف مسبقاً. افتح shell جديداً، أو أضف هذين السطرين يدوياً إلى ~/.bashrc ثم أعد تحميله.

export BUN_INSTALL="$HOME/.bun"
export PATH="$BUN_INSTALL/bin:$HOME/.npm-global/bin:$PATH"
bun --version

يطبع ذلك رقم إصدار. يعني bun: command not found أن سطر PATH مفقود من shell الذي تستخدمه، وليس أن التثبيت فشل. نفّذ ls ~/.bun/bin قبل إعادة تثبيت أي شيء.

ننتقل الآن إلى بيئة تشغيل الوكيل. Codex CLI هو الخيار الافتراضي، ويُثبَّت من npm. عيّن بادئة npm على مستوى المستخدم حتى لا يحتاج التثبيت العام إلى صلاحيات root.

npm config set prefix "$HOME/.npm-global"
npm install -g @openai/codex
command -v codex
codex

يجب أن يطبع command -v codex مساراً ضمن $HOME/.npm-global/bin. يؤدي تشغيل codex بمفرده إلى فتح واجهة CLI، حيث تسجّل الدخول باستخدام حساب ChatGPT الخاص بك. نفّذ ذلك الآن مرة واحدة، ما دمت قادراً على رؤية الشاشة.

يعمل Claude Code كبيئة تشغيل بديلة، وله مثبت خاص به.

curl -fsSL https://claude.ai/install.sh | bash
claude --version

يطبع التثبيت السليم إصداراً مثل 2.1.211 (Claude Code). نفّذ claude مرة واحدة لتسجيل الدخول. هذه العملية من الفئة نفسها، ولها مستوى الوصول نفسه إلى ملفاتك مثل أي وكيل آخر تستضيفه، ولذلك تنطبق هنا ملاحظات الحساب والتحصين الواردة في تشغيل وكيل برمجي على VPS دون تغيير.

تثبيت Deer Workflow وتثبيت الإصدار المحدد

bun install --global @deerwork-ai/deer-workflow@0.2.0
command -v deer-workflow

يطبع command -v المسار المطلق، وعادةً ما يكون /home/<your user>/.bun/bin/deer-workflow. انسخه إلى مكان ما. لا يمكن لوحدة systemd استخدام الاسم المجرد.

احتفظ بالإصدار في أمر التثبيت. يؤدي حذف @0.2.0 إلى تثبيت أحدث إصدار متاح في يوم تنفيذ الأمر. وقد يغيّر ذلك واجهة CLI ضمن مؤقت لا يراقبه أحد، خصوصاً في مشروع يتضمن 47 commit.

ضع الرسوم البيانية في مستودع git

mkdir -p ~/workflows/logs
cd ~/workflows
git init

يتحقق Codex مما إذا كان يعمل داخل مستودع git، ولذلك يتضمن CodexAgentConfig خيار skipGitRepositoryCheck للحالات التي لا يمكنك فيها تزويده بمستودع. يمكنك تزويده بمستودع على VPS الخاص بك، وينبغي لك ذلك: الرسم البياني هو شيفرة، وتنهار جدوى كتابة التهيئة ك‌شيفرة إذا لم تكن الشيفرة خاضعة للتحكم في الإصدارات. أنشئ الدليل logs الآن، لأن systemd لن ينشئه نيابةً عنك.

اكتب graph واحدة

تُعدّ workflow وحدة TypeScript عادية. فهي تصدّر meta، وهو كائن يحتوي على اسم ووصف وقائمة المراحل بالترتيب، كما تصدّر المعالج باسم default أو ضمن تصدير مسمّى هو run. تستدعي داخل المعالج الدوال المساعدة من الحزمة. يحدّد phase() المرحلة الحالية للتنفيذ، ويكتب log() سطر تقدّم، ويرسل agent() مطالبة واحدة إلى coding agent، وينفّذ parallel() قائمة من المهام في الوقت نفسه، ويدفع pipeline() قائمة من العناصر عبر عدة مراحل.

احفظ هذا الملف باسم ~/workflows/log-triage.ts.

import { agent, log, parallel, phase } from "@deerwork-ai/deer-workflow";

export const meta = {
  name: "log-triage",
  description: "Groups recent service errors and writes one short report.",
  phases: [{ title: "Collect" }, { title: "Classify" }, { title: "Report" }],
  exampleArgs: { service: "nginx", hours: 24 },
};

export default async function workflow(args: { service: string; hours: number }) {
  if (!args?.service) throw new Error("input needs a service name");

  phase("Collect");
  log(`Reading ${args.hours}h of logs for ${args.service}`);
  const found = await agent<{ patterns: string[] }>(
    `Read the last ${args.hours} hours of journalctl -u ${args.service} and list the distinct error patterns.`,
    {
      sandbox: "read-only",
      schema: {
        type: "object",
        properties: { patterns: { type: "array", items: { type: "string" } } },
        required: ["patterns"],
        additionalProperties: false,
      },
    },
  );

  phase("Classify");
  log(`Classifying ${found.patterns.length} patterns`);
  const notes = await parallel(
    found.patterns.map((pattern) => () =>
      agent(`Explain this error and its most likely cause: ${pattern}`, { sandbox: "read-only" }),
    ),
  );

  phase("Report");
  return agent(`Write a short operations report from these notes: ${JSON.stringify(notes.filter(Boolean))}`);
}

تحمل أربعة تفاصيل في هذا الملف أهمية خاصة.

  • يطلب schema في استدعاء agent() مخرجات منظّمة، ويعيد الاستدعاء الكائن بعد تحليله. أما found.patterns فهو مصفوفة فعلية يمكن لبقية graph التكرار عليها. من دون schema، يعيد agent() سلسلة نصية، وعليك تحليل نص نثري.
  • يحدّد sandbox ما يمكن لتلك الخطوة الوصول إليه. يمنع read-only عمليات الكتابة، ويسمح workspace-write بعمليات الكتابة المحمية، بينما يزيل danger-full-access الحماية. ويُضبط ذلك لكل استدعاء، لذلك يمكن لـgraph القراءة على نطاق واسع والكتابة في موضع واحد.
  • يتلقى parallel() دوال، وليس promises. ينشئ map((pattern) => () => agent(...)) قائمة من thunks، لكي يحدّد runtime وقت بدء كل منها. أما تمرير agent(...) مباشرةً فسيبدأ كل استدعاء فور إنشاء القائمة.
  • تتحول المهمة الفاشلة داخل parallel() إلى null، ويستمر التنفيذ، لأن التصميم يسمح بإتمام جزئي. لذلك لا يُعد notes.filter(Boolean) مجرد تنسيق: إذا تخطيته، تضع الفئة الفاشلة النص null في مطالبة الخطوة التالية.

تستخدم الدالة المساعدة العادية agent() runtime الافتراضي، وهو Codex. لإرسال خطوة واحدة إلى Claude Code بدلاً من ذلك، استورد فئة agent واستدعها مباشرةً.

import { ClaudeAgent } from "@deerwork-ai/deer-workflow";

const claude = new ClaudeAgent({ sandbox: "read-only" });
const summary = await claude.run<string>("Summarise ./report.md in five lines.");

هذا هو شكل agent القابل للتبديل عملياً: import واحد وconstructor واحد، بينما تبقى graph المحيطة به دون تغيير. ينتمي الخيار --agent codex|claude|pi في CLI إلى deer-workflow create، الذي ينشئ ملف workflow انطلاقاً من وصف. ولا يغيّر هذا الخيار runtime الذي يستخدمه deer-workflow run.

شغّله مرة يدوياً، ثم دون واجهة تفاعلية

cd ~/workflows
deer-workflow run ./log-triage.ts --input '{"service":"nginx","hours":24}'

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

لأغراض الأتمتة، انقل الإدخال إلى ملف. احفظ ~/workflows/input.json:

{ "service": "nginx", "hours": 24 }
deer-workflow run ./log-triage.ts --input-file ./input.json --print >> logs/run.jsonl

يُعطّل --print، بالصيغة المختصرة -p، الواجهة ويكتب تدفق الأحداث إلى stdout، بحيث يكون كل كائن JSON في سطر مستقل. لا يكتب هذا الوضع أي شيء آخر إلى stdout، لذلك يؤدي الإلحاق مباشرةً بملف .jsonl إلى إنشاء ملف يمكن تحليل كل سطر فيه.

سجل الأحداث، وما الذي تبحث عنه باستخدام grep عند الساعة 3 صباحاً

يحمل كل سطر type وsequence وtimestamp وworkflowId وdepth وscriptPath. وتكون الأنواع workflow:start وworkflow:meta وworkflow:end وworkflow:error وworkflow:phase:start وworkflow:phase:end وlog. وتحمل أحداث المراحل phase، وتحمل أحداث النهاية durationMs، بينما يحمل حدث log القيمة message، ويحمل حدث workflow:error القيمة error مع name وmessage وعادةً stack.

يكفي هذا الهيكل للإجابة عن السؤالين اللذين تطرحهما عند الساعة 3 صباحاً: هل اكتمل التشغيل، وأين توقف.

grep workflow:error logs/run.jsonl
jq -r 'select(.type == "workflow:error") | .error.message' logs/run.jsonl
jq -r 'select(.type == "workflow:phase:end") | [.phase, .durationMs] | @tsv' logs/run.jsonl
jq -r 'select(.type == "log") | .message' logs/run.jsonl

لمراقبة تشغيل جارٍ الآن، تابع الملف: tail -f logs/run.jsonl | jq -c 'select(.type == "log")'. يكتب التشغيل الواحد عدداً قليلاً من الأسطر، لكن الملف لا يتوقف عن النمو، لذلك أضف قاعدة logrotate لـ ~/workflows/logs/*.jsonl بعد تشغيل المؤقت لعدة أسابيع.

شغّله ضمن systemd

استخدم خدمة oneshot مع مؤقّت بدلاً من daemon طويل التشغيل. يبدأ الرسم البياني، ويعمل، ثم ينتهي. اكتب /etc/systemd/system/log-triage.service، مع استبدال deploy باسم المستخدم الذي تستخدمه.

[Unit]
Description=Log triage workflow
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
User=deploy
WorkingDirectory=/home/deploy/workflows
Environment=HOME=/home/deploy
Environment=PATH=/home/deploy/.bun/bin:/home/deploy/.npm-global/bin:/usr/local/bin:/usr/bin:/bin
ExecStart=/home/deploy/.bun/bin/deer-workflow run ./log-triage.ts --input-file ./input.json --print
StandardOutput=append:/home/deploy/workflows/logs/run.jsonl
StandardError=journal
TimeoutStartSec=3600

ثم /etc/systemd/system/log-triage.timer:

[Unit]
Description=Run the log triage workflow every night

[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true

[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl start log-triage.service
systemctl status log-triage.service
sudo systemctl enable --now log-triage.timer
systemctl list-timers log-triage.timer

شغّل الخدمة يدوياً أولاً. ينتهي التشغيل السليم بإلغاء تنشيط الوحدة بنجاح، ويكتسب logs/run.jsonl مجموعة من الأحداث تنتهي بـ workflow:end. عندها فقط فعّل المؤقّت. يعرض list-timers موعد التشغيل المجدول التالي، ويعني Persistent=true أن التشغيل الذي فات أثناء إيقاف الخادم سيحدث مرة واحدة عند الإقلاع التالي. يرسل StandardOutput=append: تدفق الأحداث إلى الملف ويُبقي journal لكل شيء آخر، ولذلك يظل journalctl -u log-triage.service قابلاً للقراءة.

لماذا يعمل الرسم البياني في shell لدي لكنه يفشل عند تشغيله عبر systemd؟

تحقق من هذه النقاط الأربع، بهذا الترتيب.

لا تستطيع الوحدة العثور على الملفات التنفيذية. لا يقرأ systemd أبداً ~/.bashrc، ولا يحتوي PATH الافتراضي لديه على ~/.bun/bin أو ~/.npm-global/bin. تفشل الوحدة خلال أقل من ثانية، ويعرض journalctl -u log-triage.service فشل التنفيذ عند اسم الأمر. لذلك يستخدم ExecStart مساراً مطلقاً، ولأن Environment=PATH= لا يزال يسرد الدليلين معاً: يجب أن تتمكن بيئة التشغيل نفسها من العثور على codex أو claude عند بدء خطوة الوكيل.

لا يستطيع الوكيل العثور على بيانات الاعتماد الخاصة به. يقرأ CLI الخاص بالوكيل بيانات تسجيل الدخول من الدليل الرئيسي، لذا اضبط User= وEnvironment=HOME= صراحةً، وامنحه الدليل الرئيسي الذي استخدمته لتسجيل الدخول. إذا وصل التشغيل إلى workflow:start ثم أنتج workflow:error كانت رسالته صادرة عن CLI الخاص بالوكيل لا عن شفرتك، فهذه هي المشكلة في الغالب.

يُنهى التشغيل بعد 90 ثانية. بالنسبة إلى Type=oneshot، يطبّق systemd مهلة بدء التشغيل على الأمر بأكمله، والقيمة الافتراضية هي 90 ثانية. يستغرق الرسم البياني للوكيل عدة دقائق. يسجل السجل Start operation timed out. Terminating.، وتنتهي الوحدة بحالة فشل، ويحتوي ملف السجل على جزء من التشغيل دون workflow:end. يمنحه TimeoutStartSec=3600 ساعة كاملة. استخدم infinity إذا كنت تفضّل ألا يُنهى التشغيل بسبب المهلة.

تُحل المسارات النسبية في مكان آخر. يعتمد ./log-triage.ts و./input.json على WorkingDirectory. إذا حذفت ذلك السطر، يبدأ systemd العملية في /، حيث لا يوجد أي من الملفين.

ما يُسمح للمنسّق بتنفيذه

المنسّق الذي يشغّل خطوات الوكيل وفق مؤقت هو عملية تعمل على خادمك من دون أن يراقبها أحد. هناك عنصران للتحكم وميزانية واحدة مهمة.

عنصر التحكم الأول هو العزل في كل استدعاء agent(). يُعد read-only الخيار الافتراضي المناسب لأي خطوة تقتصر على القراءة، مثل قراءة السجلات أو المقاييس أو مستودع تلخّصه. انقل الخطوة إلى workspace-write عندما تحتاج فعلاً إلى الكتابة، وقلّل مساحة الكتابة باستخدام additionalWritableDirectories بدلاً من استخدام danger-full-access مباشرة.

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

الميزانية هي المال. كل استدعاء agent() هو جلسة وكيل كاملة، ويشغّل parallel() عدة جلسات في الوقت نفسه. لذلك، فإن مخططاً يوزّع التنفيذ على اثني عشر فرعاً يشغّل اثنتي عشرة جلسة كل ليلة، سواء قرأ أحد التقرير أم لا. تنطبق القياسات والحدود الواردة في ضبط تكاليف وكلاء الذكاء الاصطناعي على VPS مباشرة على المخطط المجدول.

قبل ترقية بيئة التشغيل، اقرأ سجل التغييرات، وثبّت الإصدار الجديد المحدد، وشغّل المخطط مرة واحدة يدوياً باستخدام --print. ما يزال سطح CLI يتغير في مشروع حديث كهذا؛ إذ إن قسم Unreleased يحذف بالفعل أمراً موجوداً في 0.2.0. لا يكون المخطط الذي يعمل وفق مؤقت موثوقاً إلا بقدر الإصدار الذي ثبّتَّه وآخر تشغيل راقبته فعلياً.

FAQ

هل أحتاج إلى Bun، أم سيشغّل Node.js برنامج Deer Workflow؟

ثبّت Bun. تشير الحزمة المنشورة من خلال ملفها التنفيذي deer-workflow إلى src/cli.ts، وهو ملف مصدر TypeScript، وتذكر الوثائق أن Bun متطلب أساسي. ينفّذ Bun لغة TypeScript مباشرة، لذلك لا تحتاج إلى خطوة بناء. ثبّته باستخدام sudo apt install -y unzip ثم curl -fsSL https://bun.com/install | bash، وبعد ذلك تحقّق من التثبيت باستخدام bun --version. ستظل بحاجة إلى Node.js وnpm بشكل منفصل إذا ثبّت Codex CLI من npm.

لماذا يعمل سير العمل في الطرفية لكنه يفشل عند تشغيله عبر systemd؟

السبب في معظم الحالات هو PATH أو HOME أو مهلة بدء التشغيل. لا يقرأ systemd ملف تعريف الصدفة، لذلك يحتاج ExecStart إلى المسار المطلق لـdeer-workflow، ويحتاج Environment=PATH= إلى الدليل الذي يحتوي على codex أو claude. يقرأ CLI الخاص بالوكيل بيانات الاعتماد من $HOME، لذلك عيّن User= وEnvironment=HOME= للحساب الذي سجّلت الدخول به. كما يرث Type=oneshot مهلة بدء مقدارها 90 ثانية، ما يؤدي إلى إنهاء تشغيل الوكيل قبل اكتماله وترك Start operation timed out. Terminating. في السجل، لذلك عيّن TimeoutStartSec=3600.

كيف أستخدم Claude Code بدلاً من Codex في خطوة؟

يستخدم المساعد العادي agent() بيئة التشغيل الافتراضية، وهي Codex. استورد ClaudeAgent من الحزمة، وأنشئ نسخة منه، واستدعِ .run() للخطوات التي تريد أن يتولاها Claude Code. ينتمي الخيار --agent codex|claude|pi إلى deer-workflow create، وهو الأمر الذي ينشئ ملف سير عمل من وصف، ولا يؤثر في deer-workflow run. يحتاج أي وكيل تستخدمه إلى CLI الخاص به، وأن يكون مسجّل الدخول بالحساب نفسه الذي تعمل به الخدمة.

ما إصدار Deer Workflow الذي ينبغي أن أثبّته؟

ثبّت الإصدار الذي اختبرته تحديداً. في 19 August 2026، أحدث إصدار منشور هو 0.2.0، وقد صدر في 27 July 2026، ويحتوي المستودع على 47 عملية commit. اكتب @0.2.0، أو الإصدار الحالي عند قراءتك لهذا النص، في أمر التثبيت، واحتفظ بهذا الرقم في git بجانب الرسوم البيانية، وشغّل أحد الرسوم البيانية يدوياً بعد كل ترقية قبل أن يشغّله المؤقت مرة أخرى.