رفتن به محتوا

rtl-terminal

  • مخزن: https://github.com/Tal9392/rtl-terminal · کامیت خوانده‌شده: 7774f26 (v0.2.0، 2026-05-25) · مجوز: MIT · زبان: فقط Markdown (بدون کد) · سکو: Claude Code (هر ترمینال میزبانی؛ هدف اصلی Terminal.app در macOS)
  • دسته: افزونه (تبدیل خروجی صرفاً از طریق پرامپت، که مدل زبانی انجامش می‌دهد)

افزونه‌ای برای Claude Code که تماماً از فایل‌های دستورالعمل Markdown ساخته شده است. به مدل می‌گوید در هر پاسخی که متنی به خط عبری/عربی دارد، نویسه‌های کنترلی دوجهتی (bidi control characters) یونیکد را جاسازی کند، تا ترمینالی که UAX #9 را روی هر سطر اجرا می‌کند، اشاره‌های صریحی دربارهٔ جهت پاراگراف و جزیره‌های LTR (مسیرها، کد، انگلیسی) دریافت کند.

چگونه کار می‌کند (تأییدشده در کد)

Section titled “چگونه کار می‌کند (تأییدشده در کد)”
  • هیچ زمان اجرایی (runtime) ندارد. نه hook، نه output style، نه اسکریپت و نه فایل اجرایی. مخزن شامل .claude-plugin/plugin.json، یک مانیفست marketplace، چهار فرمان اسلش، یک skill و یک الگوی CLAUDE.md است. جست‌وجو با grep برای hookها/TERM_PROGRAM/output-style چیزی پیدا نمی‌کند.
  • سازوکار ۱، یک skill: skills/rtl-formatting/SKILL.md:1-5 یک skill است که کاربر نمی‌تواند مستقیم فراخوانی‌اش کند و توضیحش از مدل می‌خواهد آن را «automatically whenever you generate any text containing RTL script» به کار ببرد. اینکه فعال شود یا نه، به تصمیم مدل برای بارگذاری‌اش بستگی دارد.
  • سازوکار ۲، تزریق در CLAUDE.md: /rtl-terminal:enable (commands/enable.md:18-40) از مدل می‌خواهد assets/CLAUDE-block.md را میان نشانگرهای <!-- rtl-terminal:start -->/end به ~/.claude/CLAUDE.md سراسری کاربر بیفزاید. disable.md:30-40 آن را حذف می‌کند. status.md:25-35 با grep به دنبال نشانگرها می‌گردد. پس حالت «همیشه روشن» یک قاعدهٔ ماندگار در پرامپت سیستمی است.
  • نویسه‌های کنترلی تجویزشده (assets/CLAUDE-block.md:8-16، SKILL.md:11-18):
    • RLE U+202B … PDF U+202C دور هر پاراگراف، آیتم فهرست و سرعنوانِ RTL.
    • LRI U+2066 … PDI U+2069 دور مسیرها، کد، URLها و واژه‌های انگلیسی درون متن RTL. RLM U+200F صراحتاً با این استدلال رد می‌شود که «not strong enough» (CLAUDE-block.md:9).
    • LRM U+200E در آغاز هر سطر جدول Markdown، به‌علاوهٔ یک ستون اولِ LTR به‌عنوان «لنگر» (CLAUDE-block.md:14-16، SKILL.md:62-65). جدول‌هایی که خانه‌هایشان فقط RTL است توصیه نمی‌شوند و فهرست‌های شماره‌دار به جای آن‌ها پیشنهاد می‌شوند.
    • بلوک‌های کد محصور (fenced) و خروجیِ تماماً انگلیسی دست‌نخورده می‌مانند (قاعده‌های ۳ و ۶).
  • تشخیص RTL بر اساس بازهٔ نقاط کد است که مدل آن را در ذهن خود اعمال می‌کند: عبری 0590–05FF، FB1D–FB4F؛ عربی 0600–06FF، 0750–077F، 08A0–08FF، FB50–FDFF، FE70–FEFF (CLAUDE-block.md:28). بلوک‌های فرم‌های نمایشی (presentation forms) فقط به‌عنوان بازه‌های تشخیص فهرست شده‌اند و هرگز تولید نمی‌شوند.
  • هیچ تشخیصی برای سطح ترمینال ندارد. نه دسته‌بندیِ bidi / nobidi / unknown در کار است و نه بررسیِ TERM_PROGRAM، TERM یا میزبان. هر جا RTL باشد، نشانه‌ها بی‌قیدوشرط تولید می‌شوند. تنها «تشخیص»، /rtl-terminal:test است (commands/test.md:10-96) که یک محتوا را با و بدون نشانه‌ها چاپ می‌کند و از انسان می‌خواهد با چشم قضاوت کند.
  • هیچ حالت nobidi وجود ندارد، پس هرگز فرم‌های نمایشی یا متن وارونه تولید نمی‌کند. متن به ترتیب منطقی می‌ماند و فقط کنترل‌های قالب‌بندیِ نامرئی به آن افزوده می‌شود.
لایه وضعیت شاهد
۱ رمزگذاری و یکسان‌سازی ❌ پرداخته نشده. نویسه‌های قالب‌بندی (Cf) را به جریان می‌افزاید که با متن یکسان‌سازی‌شده و قابل‌جست‌وجو در تضاد است.
۲ ورودی ❌ خارج از دامنه. SKILL.md:94 می‌گوید مکان‌نمای فیلد ورودی «the terminal’s job» است.
۳ پهنا ❌ پرداخته نشده. درستی‌اش به رندرکنندهٔ میزبان (Ink/string-width) و به اینکه ترمینال این کنترل‌ها را بی‌پهنا در نظر بگیرد وابسته است. هیچ چیز این را بررسی نمی‌کند.
۴ شکل‌دهی ❌ پرداخته نشده. فرض می‌کند ترمینال عربی را شکل‌دهی (shaping) می‌کند.
۵ دوجهتی ◐ اشاره‌های صریح UAX #9 فراهم می‌کند (embeddingها + isolateها + LRM). ترمینال همچنان باید UAX #9 را، از جمله X1–X10، پیاده کرده باشد. هیچ چیز بررسی نمی‌کند که مدل واقعاً جفت‌های متوازن تولید کند.
۶ مکان‌نما، انتخاب و کپی ❌ کنترل‌ها در کپی باقی می‌مانند. README (README.md:90-91) این را «correct» می‌نامد و پیشنهاد می‌کند با tr حذفشان کنید.
۷ قلم‌ها ❌ —
۸ مالتی‌پلکسرها ❌ در نظر گرفته نشده. tmux و Zellij سطرها را دوباره رندر می‌کنند و رفتارشان با این نویسه‌های Cf آزموده نشده است.
۹ برنامه‌ها و چارچوب‌های TUI ◐ فقط Claude Code، و فقط از طریق پرامپت. راهنمایی دربارهٔ جدول‌های Markdown (SKILL.md:48-77) تنها بخشی است که مخصوص یک برنامه است.
  • «Every modern terminal supports them» (README.md:16)، و اینکه در «Terminal.app, iTerm2, WezTerm, VS Code terminal, Hyper» کار می‌کند (README.md:64). هیچ آزمون یا تصویری در مخزن نیست. ترمینال‌هایی که دوجهتی را پیاده نکرده‌اند (چندتایی هیچ پشتیبانی‌ای ندارند یا فقط پشتیبانی ناقص دارند)، این کنترل‌ها را نادیده می‌گیرند یا آن‌ها را به‌صورت گلیف یا مربع خالی (tofu) رسم می‌کنند.
  • «Verified failure mode: 2026-05-25» برای جدول‌ها (CLAUDE-block.md:14). این حکایتی است و هیچ نمونهٔ آزمونی (fixture) ندارد.
  • «~30–60 extra tokens per response» (README.md:67). اندازه‌گیری نشده است.
  • «BiDi-unaware terminals like raw tty… are vanishingly rare» (SKILL.md:96). این با توصیهٔ عیب‌یابیِ خودِ افزونه برای عوض کردن ترمینال (README.md:81-82) در تناقض است.

ارتباط با Ink (رندرکنندهٔ Claude Code)

Section titled “ارتباط با Ink (رندرکنندهٔ Claude Code)”

این افزونه هرگز به Ink دست نمی‌زند. کنترل‌ها به‌عنوان متن عادی از رندرکنندهٔ Markdown در Claude Code و چیدمان Ink عبور می‌کنند. خطرهایی که می‌توان استنباط کرد (اینجا آزموده نشده‌اند):

  1. Ink سطرها را بر اساس پهنای اندازه‌گیری‌شده می‌شکند. یک پاراگرافِ شکسته‌شده RLE را در یک سطر ترمینال و PDF را در سطری دیگر قرار می‌دهد. ترمینال‌ها دوجهتی را سطر به سطر اجرا می‌کنند، پس سطر دوم embedding خود را از دست می‌دهد.
  2. محاسبهٔ پهنای Ink باید U+202A–202E و U+2066–2069 را بی‌پهنا بشمارد. اگر چنین نکند، فاصله‌گذاری و حاشیه‌ها جابه‌جا می‌شوند.
  3. تراز جدول‌های Markdown را Claude Code محاسبه می‌کند. وجود LRM/RLE درون خانه‌ها هر خانه را به یک بافت دوجهتیِ جداگانه تبدیل می‌کند. نتیجه اینکه مالکیت دوجهتی به رندرکننده (Ink یا ترمینال) تعلق دارد، نه به جریان توکن‌های مدل.

آنچه می‌آموزیم یا برمی‌داریم

Section titled “آنچه می‌آموزیم یا برمی‌داریم”
  • MIT است، پس قابل استفادهٔ دوباره است، هرچند کد چندانی برای استفادهٔ دوباره ندارد. ایدهٔ الگوی آزمون (commands/test.md) ارزش برداشتن دارد: یک پیکرهٔ متنی واحد با و بدون کنترل‌ها، شامل یک مسیر مختلط، اعداد همراه با نشانه‌های نگارشی و یک جدول RTL. جای این در نمونه‌های آزمون انطباق (conformance fixtures) ماست.
  • راهنمایی‌اش دربارهٔ ترجیح isolateها بر نشانه‌ها برای جزیره‌های LTR (LRI/PDI به جای RLM) با بهترین شیوهٔ UAX #9 هم‌خوان است. مسیرها و URLها رایج‌ترین مورد شکست‌اند.
  • دردی واقعی از کاربران را مستند می‌کند: جدول‌های Markdown که جهت پایهٔ سطر سرعنوانشان RTL تعیین می‌شود، ستون‌هایشان وارونه می‌شود. این مورد مفیدی برای پیکرهٔ لایهٔ ۹ است.

محدودیت‌ها و الگوهای نادرست

Section titled “محدودیت‌ها و الگوهای نادرست”
  • دست‌کاری محتوا به‌عنوان راه‌حل نمایشی. نویسه‌های قالب‌بندیِ نامرئی را در متن منطقی می‌نویسد، پس این نویسه‌ها به کلیپ‌بورد، لاگ‌ها، رونوشت‌ها، grep و git راه پیدا می‌کنند. اصول ما فیلترهای نمایشی‌ای را که متن را بازنویسی می‌کنند رد می‌کند. این شکلی ملایم‌تر است (بازچینی ندارد) اما از همان دسته است.
  • اجرای غیرقطعی. درستی‌اش به این وابسته است که یک مدل زبانی به یاد داشته باشد RLE/PDF و LRI/PDI را متوازن کند. یک جفتِ نامتوازن در یک ترمینالِ مطابق با استاندارد، باقی سطر را خراب می‌کند.
  • از embeddingهایی استفاده می‌کند که در عمل منسوخ‌اند. برای پاراگراف‌ها RLE/PDF به جای RLI/PDI یا FSI/PDI. UAX #9 isolateها را توصیه می‌کند، و embeddingها به نویسه‌های خنثای پیرامون نشت می‌کنند.
  • هیچ تشخیص سطحی ندارد. همان بایت‌ها به ترمینال‌های دارای دوجهتی (جایی که زائد یا زیان‌بارند)، به ترمینال‌های بدون دوجهتی (جایی که کمکی نمی‌کنند) و به میزبان‌های غیرترمینالی (VS Code، وب) فرستاده می‌شوند.
  • ~/.claude/CLAUDE.md سراسری کاربر را تغییر می‌دهد، آن هم با ویرایش‌هایی که مدل انجام می‌دهد، که شکننده است (status.md:35 از هم‌اکنون بلوک‌های تکراری را پیش‌بینی کرده است).
  • هیچ کاری برای دغدغه‌های خاص فارسی (نیم‌فاصله، ارقام فارسی، یای و کاف عربی در برابر فارسی) انجام نمی‌دهد.

یک پروژهٔ مهدی بانشی · mbaneshi.ir