Skip to content

أداة سطر الأوامر (CLI)

أداة سطر الأوامر الرسمية لـ شوغي دوجو. انشر المقالات، وارفع المباريات، وأتمتة كل ما تفعله في المتصفح من الطرفية. الأوامر نفسها تعمل على macOS و Windows و Linux.

1 المطلوب: Node.js 20 أو أحدث

الأداة نفسها بلا اعتماديات. كل ما تحتاجه هو Node.js — وطريقة تثبيته هي الشيء الوحيد الذي يختلف بين الأنظمة.

macOS

باستخدام Homebrew:

brew install node
node --version
Windows

باستخدام winget (المثبّت الرسمي يفي بالغرض أيضًا):

winget install OpenJS.NodeJS.LTS
node --version
Linux

على Debian / Ubuntu — استخدم مدير الحزم الخاص بك على التوزيعات الأخرى:

curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs
node --version

2 التثبيت

الأمر نفسه على الأنظمة الثلاثة، لكن على Linux ثبّته في مجلدك الشخصي. التثبيت على مستوى النظام يحتاج root، ولا يستحق أمرٌ سطريٌّ اللجوء إلى sudo.

macOS

نفّذ:

npm install -g @shogidojo/cli
Windows

الأمر نفسه في PowerShell:

npm install -g @shogidojo/cli
Linux

في مجلدك الشخصي، فلا حاجة إلى sudo. أضف السطر الثاني أيضًا إلى ملف إعداد الصدفة (~/.bashrc أو ~/.zshrc) ليجده أي نافذة طرفية جديدة:

npm install -g --prefix ~/.local @shogidojo/cli
export PATH="$HOME/.local/bin:$PATH"

تحقّق من التثبيت:

shogidojo --version
shogidojo --help

3 تسجيل الدخول

تستوثق الأداة بمفتاح API شخصي. المفتاح يفعل كل ما يفعله حسابك، فتعامل معه كما تتعامل مع كلمة المرور. ويمكن أن يكون لأداة الأتمتة مفتاح مسمّى خاص بها، للقراءة فقط إن كانت لا تفعل سوى القراءة.

الطريقة المعتادة. يفتح المتصفح، تسجّل الدخول، ويعود المفتاح من تلقاء نفسه — لا يظهر أبدًا في سطر الأوامر، فلا يصل إلى سجل الصدفة:

shogidojo login --browser

على جهاز وصلت إليه عبر SSH لا يكفي ‎--browser‎ وحده: يعود المفتاح إلى 127.0.0.1 على الجهاز الذي نفّذ الأمر، فلا يجد المتصفح على حاسبك من يسلّمه إليه. مرّر منفذًا تختاره أنت:

ssh -L 47311:127.0.0.1:47311 you@host
shogidojo login --browser --port 47311

أو الصق مفتاحًا. يُقرأ من الدخل القياسي، فلا يصل إلى سجل الصدفة:

shogidojo login --stdin

حيث لا يوجد متصفح، كما في CI، مرّره عبر البيئة. لا يُكتب شيء على القرص:

SHOGIDOJO_TOKEN=rustify… shogidojo whoami

لـ CI أو Windmill أو أي أتمتة أخرى، أصدِر مفتاحًا مسمّى منفصلًا؛ ويبقى المفتاح الذي على جهازك صالحًا. يُعرض المفتاح مرة واحدة (لا يحمل stdout سوى المفتاح) ولا يُحفظ على هذا الجهاز. ومع ‎--read-only‎ يستطيع القراءة دون النشر أو تغيير أي شيء:

shogidojo token create --name windmill --read-only --days 90

اعرض المفاتيح التي تملكها (الاسم، والنطاق، وتاريخ الإنشاء، وآخر استخدام، والانتهاء) وألغِ أحدها. ‏`app` هو مفتاح الحساب، أي الذي تُصدره صفحة الإعدادات:

shogidojo token list
shogidojo token revoke 3

يُحفظ المفتاح في ~/.config/shogidojo/config.json بصلاحيات 0600 (وفي Windows %APPDATA%\shogidojo). للاطلاع عليه أو حذفه:

shogidojo whoami
shogidojo logout

4 الاستخدام

الأوامر المسمّاة اختصارات. كل ما يفعله التطبيق يمكن بلوغه عبر call.

نشر مقال:

shogidojo post create --title "..." --body-file note.md --tag 居飛車

رفع سجل مباراة:

shogidojo kif upload game.kif --dir /2026

اعرف المحرّكات المتاحة لك، وحلّل مباراة، وتابع التقدّم:

shogidojo engines
shogidojo analyze game.kif --seconds 5
shogidojo jobs

أنشئ لغزًا من مباراة. ‎--ply 44‎ يسأل عن النقلة 44، ويعرض الوضع بعد النقلة 43. يمكن أن يكون ‎--answer‎ نقلة لم تُلعب في المباراة (USI، أو تدوينًا مثل △5五歩)؛ وعندها تحتفظ البطاقة أيضًا بالنقلة التي لُعبت:

shogidojo quiz create --game user-1-… --ply 44 --answer △5五歩 --note "Suggested in the post-mortem" --deck Ryuo --public

كل ما عدا ذلك — ‏--query للقراءة، ويُحذف للكتابة:

shogidojo call post.list --query --input '{"page":1}'
shogidojo call quiz.createDeck --input '{"name":"..."}'

كل ما يمكن سؤال هذا الخادم عنه. هذه القائمة هي بالضبط ما يأخذه call:

shogidojo procedures --grep quiz

5 كتابة منشور

نص ‎post create‎ هو Markdown، مع إضافتين لتضمين الرقع والمباريات.

‏[sfen:<SFEN>] يرسم وضعًا، و[game:<gameId>] يضمّن بطاقة مباراة. وكل ما عدا ذلك Markdown عادي:

## After ▲7六歩 △3四歩

[sfen:lnsgkgsnl/1r5b1/pppppp1pp/6p2/9/2P6/PP1PPPPPP/1B5R1/LNSGKGSNL b - 3]

[game:user-1-…]

تبدأ المباراة المستوردة بحالة PRIVATE. تظهر بطاقة [game:] الخاصة بها لك وحدك، وتكون فارغة لكل قارئ آخر. انشرها أثناء استيرادها بـ ‎--public‎، أو اترك ذلك لـ ‎post create --game‎ الذي يُلحق رمز [game:] ويتوقف إذا كانت مباراة PRIVATE ستدخل منشورًا PUBLIC (أضف ‎--publish-game‎ لنشرها أولًا):

shogidojo kif import game.kif --public
shogidojo post create --type KIFU --title "..." --body-file note.md --game user-1-… --publish-game

لوضع المواقف المهمة في مقال، خذ SFEN بعد النقلة N وضعه في [sfen:] (‏0 هو البداية؛ ومن دون ‎--ply‎ يكون الوضع الأخير):

shogidojo kif position user-1-… --ply 60

لاستخدام المخطط نفسه في مقال في مكان آخر، صدّره بصيغة SVG. لا يحتاج ‎--sfen‎ إلى حساب ولا إلى شبكة؛ ويأخذ ‎--game‎ الوضع واللاعبين ومربع النقلة الأخيرة من مباراة. وللحصول على PNG حوّل ملف SVG (rsvg-convert أو ImageMagick أو متصفح):

shogidojo diagram --sfen "lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL b - 1" -o start.svg
shogidojo diagram --game user-1-… --ply 60 -o move60.svg
rsvg-convert -o move60.png move60.svg

‎--type‎ مجرد وسم ومرشّح للخلاصة؛ ويُعرض النص بالطريقة نفسها. ARTICLE مقال، وKIFU يعرض سجل مباراة، وBOOK يعرض كتابًا.

يطبع ‎post create‎ رابط المنشور ‎/posts/<id>‎. صفحة المباراة هي ‎/review/<gameId>‎ (و‎/game/<id>‎ هي الرقعة المباشرة)، وهي ما يطبعه ‎kif import / upload‎:

Posted #12  https://shogidojo.online/posts/12
Imported game.kif as user-1-…
  https://shogidojo.online/review/user-1-…  (private — only you can open it)

الحدود: العنوان 200 حرف، والنص 50,000، وحتى 20 وسمًا بطول 40 حرفًا لكل منها. تتوقف الأداة قبل إرسال أي شيء يتجاوزها.

6 إجراءات call

يخبرك ‎--describe‎ بما يأخذه call. يجيب الخادم بمخطط Zod الذي يتحقق به من المدخلات، بصيغة JSON Schema، فلا يمكن أن يبتعد عن الحقيقة. لا يُعرض شكل القيمة المُعادة إلا للإجراءات التي تعلنه؛ والشائعة منها أدناه (أضف ‎--query‎ للقراءة).

اعرف ما يأخذه إجراء ما:

shogidojo procedures --describe quiz.import

سجلات المباريات:

game.importKifFromText        {"kifText":"…","dir":"/2026"}
  → {"game_id":"user-1-…"}
game.setGameVisibility        {"gameId":"user-1-…","visibility":"PUBLIC"}
  → {"success":true}
game.getFullGameById (read)   {"gameId":"user-1-…"}
  → {"game_id":…, "visibility":…, "moves":[{"id":1, "moveNumber":0, "sfen":"…",
       "children":[{"childId":2, "usi":"7g7f", "notation":"▲7六歩"}]}, …]}
game.applyMove (read)         {"sfen":"…","move":"△5五歩","lastUsi":"7g7f"}
  → {"sfen":"…","usi":"5d5e","notation":"△5五歩","nextSfen":"…"}

المنشورات:

post.create   {"type":"KIFU","title":"…","body":"…","tags":["居飛車"],"visibility":"PUBLIC"}
  → {"id":12, …}

الألغاز (‏playedUsi / playedNotation هي النقلة التي لُعبت في المباراة، وgameId المباراة المصدر؛ وكلاهما اختياري):

quiz.import   {"title":"…","visibility":"PUBLIC","gameId":"user-1-…",
               "items":[{"sfen":"…","answerUsi":"5d5e","answerNotation":"△5五歩",
                         "nextSfen":"…","note":"…",
                         "playedUsi":"8a7c","playedNotation":"△7三桂"}]}
  → {"deckId":5,"listIds":[9]}
  (or {"deck":{"title":"…"},"lists":[ …the same list… ]} for a named deck)

7 إذا حدث خطأ

ثلاثة أسباب تغطي معظم الحالات.

رسالة "Unsupported engine" أو خطأ في الصياغة تعني غالبًا أن Node قديم. المطلوب 20 أو أحدث:

node --version

إذا فشل التثبيت العام بخطأ EACCES، انقل مسار التثبيت إلى مجلدك الشخصي بدل اللجوء إلى sudo:

npm config set prefix ~/.local
export PATH="$HOME/.local/bin:$PATH"

يطبع ‎login --browser‎ رابطًا، لكن عنوان العودة داخله يشير إلى 127.0.0.1 على الجهاز الذي طبعه. فتح ذلك الرابط على جهاز آخر يسجّل الدخول هناك ولا يصل المفتاح إلى أي مكان. عبر SSH مرّر منفذًا وأعطه بـ ‎--port‎، أو الصق المفتاح بـ ‎--stdin‎؛ وكلاهما أعلاه:

shogidojo login --stdin