پرش به محتوای اصلی
پرش به محتوای مقاله

درون راهکار shell.online برای رفع محدودیت‌های دسترسی macOS

·۲۹ شهریور ۱۴۰۵۶ دقیقه مطالعه
launchd چهار دایرکتوری به دیمون ما داد. هر عامل کدنویسی روی ماشین، جای دیگری نصب شده بود.
launchd چهار دایرکتوری به دیمون ما داد. هر عامل کدنویسی روی ماشین، جای دیگری نصب شده بود.
اشتراک‌گذاری
واقعاً چه چیز جدید است؟

جایگزینی شناسایی ایستا با یک «کاوشگر شل» پویا که محیط تعاملی کاربر را شبیه‌سازی می‌کند تا ابزارهای نصب‌شده در مسیرهای غیر استاندارد macOS شناسایی شوند.

تصور کنید با این پیام خطا مواجه شوید: «Claude Code در این سیستم یافت نشد». این یک خطای ساده نیست، بلکه نشانه‌ای از یک نقص ساختاری در نحوه شناسایی ابزارهای هوش مصنوعی توسط shell.online در سیستم‌عامل macOS است. این شکست نشان داد که سیستم شناسایی ابزارها در محیط‌های مدرن توسعه دچار مشکل است.

برای حل این مشکل قدیمی که با گسترش نصب‌های شخصی‌سازی‌شده‌ی عامل‌های هوش مصنوعی (per-user AI agent installations) تشدید شده بود، تیم توسعه در ۲۰ سپتامبر ۲۰۲۶ تغییرات لازم را در قالب کامیت e7f891e در شاخه main اعمال کرد.

بسیاری از برنامه‌نویسان، عامل‌های کدنویس را از طریق اسکریپت‌های curl یا npm نصب می‌کنند و فایل‌های اجرایی را در دایرکتوری‌هایی مانند ~/.local/bin یا /opt/homebrew/bin قرار می‌دهند. این مسیرها معمولاً از طریق فایل‌های پیکربندی شل (مانند .zshrc یا .bash_profile) به محیط سیستم اضافه می‌شوند. اما وقتی ابزاری به عنوان یک سرویس پس‌زمینه (Background Service) اجرا می‌شود، این فایل‌ها را نمی‌خواند و در نتیجه، عامل هوش مصنوعی برای سیستم نامرئی می‌شود.

این وضعیت شبیه به این است که ابزار تخصصی شما در یک کشوی خاص باشد؛ ترمینال شما می‌داند کشو کجاست چون در تنظیمات به او گفته‌اید، اما سرویس پس‌زمینه مثل دستیاری نابیناست که فقط چهار کمد استاندارد کارخانه را می‌گردد و اگر ابزار آنجا نباشد، گزارش می‌دهد که اصلاً وجود ندارد.

همان‌طور که در تحلیل‌های قبلی ما درباره‌ی چالش‌های استقرار ابزارهای توسعه در محیط‌های بدون سر (Headless) اشاره کردیم، تضاد بین محیط تعاملی کاربر و سرویس‌های سیستمی همواره یک نقطه ضعف بوده است.

جزئیات شکست در شناسایی

به گزارش dev.to، سامانه shell.online از یک دیمون (Daemon) برای گزارش ابزارهای در دسترس استفاده می‌کند. این ابزارها شامل چارچه‌هایی مانند Claude Code، Codex، Hermes و OpenClaw هستند. لیست این چهار مورد در فایل cmd/shell/harness.go مدیریت می‌شود و هر کدام به یک نام دستور خاص نگاشت شده‌اند. این تلاش برای یکپارچگی در حالی است که استاندارد AGENTS.md نیز سعی دارد دستورالعمل‌های برنامه‌نویسی را میان ابزارهای مختلف AI یکسان کند تا تعامل با این عامل‌ها پیش‌بینی‌پذیرتر شود.

مکانیزم شناسایی بر پایه تابع exec.LookPath است که صرفاً بررسی می‌کند آیا یک دستور در مسیر فعلی (PATH) وجود دارد یا خیر. تیم توسعه به طور صریح از اجرای مستقیم ابزارها برای خواندن رشته‌های مربوط به نسخه (version strings) خودداری کرده است؛ زیرا چندین مورد از این عامل‌ها برای شروع به کار چندین ثانیه زمان نیاز دارند و نمایش یک برچسب در مرورگر، ارزش پرداخت هزینه پردازشی اجرای آن‌ها را ندارد.

قبل از نسخه ۰.۱۷.۰، دیمون مسیر PATH کاربر را از ترمینالی که آن را اجرا کرده بود به ارث می‌برد. این روش کار می‌کرد زیرا ترمینال پیش از آن پروفایل کاربر را بارگذاری کرده بود. اما مشکل زمانی شروع شد که دیمون به یک سرویس کاربری (یک LaunchAgent در macOS یا یک واحد systemd در لینوکس) تبدیل شد تا امکان ایجاد نشست‌های مبتنی بر مرورگر در ماشین‌های بدون سر (headless) فراهم شود.

در macOS، سرویس launchd یک PATH به شدت محدود ارائه می‌دهد که تنها شامل چهار دایرکتوری است: /usr/bin، /bin، /usr/sbin و /sbin. از آنجایی که تقریباً تمام عامل‌های هوش مصنوعی مدرن خارج از این پوشه‌های سیستمی قرار دارند، دیمون گزارش می‌داد که هیچ ابزاری در دسترس نیست، حتی زمانی که ابزارها نصب بودند و در ترمینال به درستی کار می‌کردند. این یک مشکل قدیمی و شناخته شده است؛ برای مثال، Mutagen در فوریه ۲۰۱۹ مشکل مشابهی را گزارش کرد که در آن launchd نمی‌توانست Docker را پیدا کند زیرا /usr/local/bin در مسیر دیمون وجود نداشت.

راهکار فنی: کاوشگر شل (The Shell Probe)

برای حل این بحران، تیم توسعه مکانیزم جدیدی را در فایل cmd/shell/tool_path.go معرفی کرد. حالا دیمون به جای حدس زدن PATH، در لحظه شروع به طور فعال شل کاربر را با استفاده از دستور $SHELL -lic و اسکریپتی که $PATH فعلی را چاپ می‌کند، کاوش کرده و سپس یک بار تابع os.Setenv را فراخوانی می‌کند.

این رویکرد برای مدیریت پیچیدگی‌های محیط‌های توسعه مدرن با جزئیات زیر طراحی شده است:

  • بارگذاری تعاملی (Interactive Loading): پرچم -i در کنار -l استفاده شده است. این کار تضمین می‌کند که فایل‌های rc تعاملی خوانده شوند. این موضوع برای ابزارهایی مانند nvm که به صورت توابع شل در پروفایل‌های تعاملی تعریف شده‌اند و برای شل‌های صرفاً ورود (login-only) نامرئی هستند، حیاتی است. با توجه به اینکه دو مورد از چهار چارچوب پشتیبانی شده، بسته‌های npm هستند، این قابلیت ضروری است.
  • تجزیه نشانگرها (Marker Parsing): دیمون درخواست PATH را در نشانگرهای خاصی (<<<shell-online-path: و :shell-online-path>>>) قرار می‌دهد تا پیام‌های «پیام روز» (MOTD)، اعلان‌های نسخه یا هر متن دیگری که شل‌های تعاملی اغلب چاپ می‌کنند، فیلتر شوند.
  • مهلت‌های زمانی ایمنی (Safety Timeouts): یک ضرب‌الاجل ۵ ثانیه‌ای اعمال شده و stdin روی nil تنظیم شده است. اگر فایل rc کاربر به دلیل یک فراخوانی شبکه متوقف شود یا منتظر یک اعلان (prompt) بماند، دیمون از شروع به کار باز نمی‌ماند.
  • وضعیت خروج (Exit Status): اگر نشانگرها در خروجی حضور داشته باشند، وضعیت خروج غیرصفر نادیده گرفته می‌شود. این امر تضمین می‌کند که فایل‌های rc که با یک دستور شکست‌خورده به پایان می‌رسند، همچنان اجازه دهند دیمون PATH صحیح را استخراج کند.
  • جایگزین‌های شل (Shell Fallbacks): از آنجایی که متغیر SHELL اغلب در محیط launchd و systemd تعریف نشده است، دیمون شل کاربر را از /etc/passwd می‌خواند و در macOS به طور پیش‌فرض از /bin/zsh و در سایر سیستم‌ها از /bin/sh استفاده می‌کند.

مدیریت موارد خاص و لبه‌ای

این پیاده‌سازی همچنین تفاوت‌های خاص هر شل را در نظر می‌گیرد. به عنوان مثال، شل fish مسیر PATH را به صورت یک لیست ذخیره می‌کند و آن را با فاصله (space) به جای دو نقطه چاپ می‌کند. دیمون اکنون مقادیری را که فاقد دو نقطه هستند و دارای دو یا چند فیلد می‌باشند (به طوری که هر فیلد با / شروع شود) شناسایی کرده و آن‌ها را مجدداً با دو نقطه متصل می‌کند. همچنین یک تست خاص گنجانده شده تا اطمینان حاصل شود که دایرکتوری واحدی که در نامش فاصله دارد، دست‌نخورده باقی بماند.

برای کاربران nvm، سیستم به طور خاص فایل ~/.nvm/alias/default را می‌خواند تا مسیر باینری نسخه‌بندی شده را بسازد. این کار از انتخاب تصادفی نسخه قدیمی Node.js بر اساس مرتب‌سازی الفبایی (جایی که v9 بعد از v22 ظاهر می‌شود) جلوگیری می‌کند.

ترتیب ادغام (Merge order) نیز به طور دقیق تعریف شده است: ابتدا PATH ترمینال در اولویت است، سپس PATH داده شده توسط سرویس و در نهایت یک لیست جایگزین (fallback). این تضمین می‌کند که اگر دو نسخه از باینری Claude وجود داشته باشد، دیمون همان نسخه‌ای را پیدا کند که ترمینال کاربر استفاده می‌کند.

دایرکتوری‌های جایگزین (Fallback Directories)

در صورتی که کاوشگر شل شکست بخورد، سیستم از یک لیست منتخب از دایرکتوری‌های رایج استفاده می‌کند که تنها مواردی که واقعاً روی ماشین وجود دارند فیلتر می‌شوند:

  • ~/.local/bin
  • /opt/homebrew/bin
  • /usr/local/bin
  • ~/.bun/bin
  • ~/.cargo/bin
  • ~/go/bin
  • ~/.volta/bin

در ویندوز، این کاوش (probe) غیرضروری است. مدیریت سرویس ویندوز (Windows service manager) در حال حاضر PATH ماشین و کاربر را در اختیار سرویس قرار می‌دهد، بنابراین در آنجا فقط دایرکتوری‌های جایگزین اعمال می‌شوند.

هزینه راهکار و تحلیل معماری

این اصلاحات یک هزینه پردازشی کوچک ایجاد می‌کند: دیمون اکنون در هر بار شروع، فایل‌های rc تعاملی کاربر را یک بار اجرا می‌کند. اگرچه این رفتار مشابه باز کردن یک ترمینال است، اما به این معنی است که هر تغییری در PATH در فایل پیکربندی تا زمان ری‌استارت دیمون شناسایی نخواهد شد.

یک جایگزین دیگر، ثابت کردن (freezing) PATH در فایل plist در هنگام نصب بود. نصب‌کننده سرویس در حال حاضر شش متغیر را از طریق servicePassthrough در فایل cmd/shell/service.go منتقل می‌کند (که همگی با SHELL_ONLINE_* نام‌گذاری شده‌اند)، اما PATH یکی از آن‌ها نیست. تیم توسعه افزودن آن را رد کرد زیرا یک PATH ثابت به محض اینکه کاربر نسخه Node را از طریق nvm تغییر دهد، منسوخ می‌شود.

این کشمکش معماری نشان‌دهنده یک روند گسترده‌تر در ابزارهای هوش مصنوعی است. همان‌طور که در مخزن Pilot Protocol دیده می‌شود، ابزارها به طور فزاینده‌ای تلاش می‌کنند تا خود را «یافتنی» کنند. آن‌ها این کار را با ایجاد symlink برای باینری‌ها در /usr/local/bin انجام می‌دهند تا از شل‌های غیرتعاملی، کارهای cron، CI و عامل‌های هوش مصنوعی پشتیبانی کنند. اسکریپت install.sh در Pilot Protocol مسیر ~/.pilot/bin را به پروفایل‌های شل اضافه کرده و از sudo بدون رمز عبور برای لینک کردن pilotctl و pilot-daemon به /usr/local/bin استفاده می‌کند تا CLI در شل‌های غیرتعاملی شناسایی شود.

در مورد shell.online، دیمون در واقع فراخواننده‌ای با «PATH نازک» است و اکنون باید بار سنگین یافتن ابزارهایی که توسط توسعه‌دهندگان دیگر نصب شده‌اند را به دوش بکشد.

به‌روزرسانی پیام‌های کاربری

اعلان‌های مرورگر نیز به‌روزرسانی شده‌اند. پیش از این گفته می‌شد ابزار «یافت نشد» و دستور «در صورت عدم نصب ابزار، با شکست مواجه خواهد شد». این پیام برای کاربرانی که ابزار را در پنجره‌ای دیگر باز می‌دیدند، گمراه‌کننده بود. این چالش در دسترسی، ممکن است بخشی از دلیل نرخ پایین استفاده باشد؛ چرا که تحلیل‌ها نشان داده ۸۷.۵٪ از عامل‌های سفارشی Claude Code در یک ماه هیچ فراخوانی نداشتند.

اکنون سیستم توصیه می‌کند که اگر ابزار نصب است، کاربر باید نسخه shell را در آن ماشین به‌روزرسانی کرده و مجدداً shell auth را اجرا کند، زیرا نسخه‌های قدیمی‌تر نمی‌توانستند ابزارها را در PATH شل ببینند. این اصلاح در حال حاضر در لیست «Unreleased» در تغییرات (changelog) بعد از نسخه ۰.۱۹.۰ قرار دارد؛ به این معنی که در شاخه main موجود است اما هنوز در یک نسخه تگ‌دار منتشر نشده است. اگر ماشینی که سرویس روی آن نصب است، هیچ عاملی را گزارش نمی‌کند، این اولین موردی است که باید بررسی شود.

گام بعدی شما

  • اگر از macOS استفاده می‌کنید و عامل‌های کدنویس شما در shell.online شناسایی نمی‌شوند، دیمون سرویس را ری‌استارت کنید.
  • بررسی کنید که آیا مسیرهای نصب ابزارهای شما در فایل .zshrc یا .bash_profile به درستی تعریف شده است.
  • برای پایداری بیشتر، از ایجاد symlink برای ابزارهای حیاتی در مسیر /usr/local/bin استفاده کنید.

اما داستان سخت‌افزاری این تحول حتی شگفت‌انگیزتر است — به تحلیل ما درباره‌ی تراشه‌های Blackwell مراجعه کنید.

چرا این موضوع مهم است؟

این اصلاح باعث می‌شود توسعه‌دهندگان macOS بتوانند بدون تغییر در ساختار نصب ابزارهای خود، از قابلیت‌های عامل‌محور در محیط‌های ابری و مرورگر استفاده کنند. اعتبار این راهکار در حل یک مشکل قدیمی (Legacy) است که حتی ابزارهای بزرگی مثل Docker نیز با آن مواجه بوده‌اند.

تأثیر برای ایران

این به‌روزرسانی برای برنامه‌نویسان ایرانی که از macOS و ابزارهای کدنویسی AI استفاده می‌کنند، تجربه کاربری را بهبود می‌بخشد و نیاز به تنظیمات دستی پیچیده برای شناسایی ابزارها را از بین می‌برد.

·نگاه ما
تحریریه دات‌هوش

این تغییر نشان می‌دهد که حتی پیشرفته‌ترین ابزارهای هوش مصنوعی همچنان با مسائل ابتدایی مدیریت محیط (Environment Management) در سیستم‌عامل‌ها دست‌وپنجه نرم می‌کنند. در واقع، شکاف بین «محیط تعاملی کاربر» و «سرویس‌های سیستمی» به یک گلوگاه برای استقرار عامل‌های خودگردان تبدیل شده است. به نظر ما، راهکار نهایی احتمالاً در استانداردسازی نحوه معرفی ابزارها به سیستم (مانند پروتکل‌های ثبت سرویس) است، نه کاوش‌های دستی در فایل‌های تنظیمات شل.

منابع

این گزارش با خط‌لولهٔ خودکار دات‌هوش از منابع معتبر جهانی تدوین و زیر نظر تحریریه منتشر شده است. روش کار ما

گفتگو

پنج‌شنبه‌های هوش‌محور

بسته‌ی هفتگی دات‌هوش

۵ خبر، ۲ ابزار، ۱ پرامپت در هر شماره. به‌زودی راه‌اندازی می‌شود — هر پنج‌شنبه صبح.

خبر کلیدی
ابزار کاربردی
پرامپت حرفه‌ای
تحلیل پژوهش
به‌زودی
زاویه‌ی ایرانی
به‌زودی
تمرین این هفته
به‌زودی

راهنماهای دات‌هوش

راهنماهای کاربردیِ دات‌هوش برای کار با هوش مصنوعی — از همین‌جا شروع کنید:

دات‌هوش

راهنمای فارسی هوش مصنوعی — با نگاه به ایران

اخبار روزانه، معرفی ابزارها و مدل‌ها، و آموزشِ کار با هوش مصنوعی؛ همیشه با این پرسش که از ایران چه چیزی کار می‌کند و چه چیزی نه.