رفع مشکل

مشکل‌های رایج و راه‌حلشان. هر وقت شک داشتید، این را اجرا کنید:

سورس در GitHub ↖این صفحه ترجمهٔ صفحهٔ انگلیسی است؛ اگر جایی با هم فرق داشتند، صفحهٔ انگلیسی درست است. انگلیسی
sh
aipager doctor

همهٔ بررسی‌های پایین را به ترتیب اجرا می‌کند و برای هر کدام که شکست بخورد، راه‌حل اصلی را چاپ می‌کند. کدش: aipager/doctor.py.

«Another aipager daemon already owns the socket»#

دو aipager نمی‌توانند یک سوکت کنترل مشترک داشته باشند. این خطا یعنی یک aipager هنوز اجرا می‌شود و روی آن جواب می‌دهد (سوکت ‎$XDG_RUNTIME_DIR/aipager.sock است، یا وقتی ‎$XDG_RUNTIME_DIR تنظیم نشده ‎/tmp/aipager.sock). فایل سوکتی که از یک aipager کرش‌کرده جا مانده مشکلی نیست: شروع بعدی پاکش می‌کند و یک سوکت جدید باز می‌کند. اول aipager در حال اجرا را متوقف کنید:

sh
aipager service stop          # اگر به‌شکل سرویس اجرا می‌شود
pkill -f 'aipager start'      # در غیر این صورت

اگر بررسی سوکت آن را نبیند، aipager start باز هم با aipager is already running (pid=N) شروع نمی‌شود و فایل قفلش را نام می‌برد (‎~/.local/share/aipager/daemon.lock): همان پروسه را به همان روش متوقف کنید.

ربات تلگرام جواب نمی‌دهد#

  1. ‏aipager status: اگر ردیف aipager می‌گوید not running، اجرایش کنید.
  2. ‏aipager doctor: بررسی‌های token_valid و chat_reachable از اول تا آخر با API تلگرام تماس می‌گیرند و خطای دقیق را نشان می‌دهند.
  3. چت اشتباه: aipager config را اجرا کنید و Test bot reachability را انتخاب کنید. برای درست کردن یک چت خصوصی اشتباه، چت درست را با Add a DM scope اضافه کنید (پیدا کردن آیدی‌ها را ببینید) و بعد چت اشتباه را زیر Edit a scope حذف کنید.
  4. در ربات هیچ‌وقت ‎/start زده نشده: ربات را در تلگرام باز کنید و یک بار Start را بزنید.

کارت‌های در حال کار کند شده‌اند#

تلگرام تقریباً یک پیام در ثانیه به هر چت اجازه می‌دهد (و ۲۰ پیام در دقیقه به یک گروه). هر پیام و هر ویرایش حساب می‌شود. aipager به هر چت سهمیهٔ خودش را می‌دهد، حدود یک درخواست در ثانیه با کمی جا برای چند درخواست پشت هم، و کارت‌های در حال کار آن چت آن را با هم تقسیم می‌کنند. نشانگر «در حال تایپ…» هم جزو همین سهمیه است، به‌عنوان کم‌اهمیت‌ترین چیزی که چت می‌فرستد («حباب در حال تایپ» را پایین‌تر ببینید).

سهم حباب اول کنار گذاشته می‌شود (هر ۴٫۵ ثانیه یک درخواست تا وقتی قدیمی‌ترین کار در حال اجرای چت کمتر از ده دقیقه از شروعش گذشته، و هرچه کار طولانی‌تر شود کمتر؛ «حباب در حال تایپ» را ببینید) و کارت‌ها بقیه را تقسیم می‌کنند. پس یک کارت در چت خصوصی تقریباً هر ۴٫۸ ثانیه آپدیت می‌شود؛ با دو سشن در حال کار در یک چت، هر کارت تقریباً هر ۹٫۷ ثانیه؛ با سه سشن، تقریباً هر ۱۴٫۵ ثانیه. کارت کندتر یعنی سهمیه دارد کار می‌کند، نه باگ. جواب‌ها، پاسخ‌ها و واکنش به دکمه‌ها هیچ‌وقت برای جا باز کردن برای یک کارت کند نمی‌شوند: سهم رزروشده‌ای دارند، و ویرایش کارتی که سهم کافی ندارد فقط جا می‌افتد و در تیک بعدی دوباره امتحان می‌شود، نه اینکه جلوی جواب شما صف بکشد.

در گروه سقف ۲۰ درخواست در دقیقه است، هر چند سشن که در آن باشد، و حباب به‌تنهایی دو سوم آن را مصرف می‌کرد. کارت‌های گروه روی هم هر ۱۰ ثانیه یک آپدیت دارند (برای یک کارت ۱۱ ثانیه) و حباب بقیه را می‌گیرد؛ برای همین در گروه گاهی یکی دو ثانیه قطع می‌شود.

برای سریع‌تر کردن کارت‌ها: سشن‌های همزمان کمتری در هر چت اجرا کنید، یا پرکارترین‌ها را به یک چت جدا ببرید (aipager config). می‌توانید STREAM_EDIT_INTERVAL (پیش‌فرض 1.2، سرعت وقتی کارت دارد متن نشان می‌دهد) و BUSY_EDIT_INTERVAL (پیش‌فرض 3.0، وقتی کارت آرام است) را هم به‌عنوان متغیرهای محیطی aipager تنظیم کنید (تنظیمات محیطی را ببینید). گذاشتن هر کدام پایین‌تر از کف هر چت ضرری ندارد و چیزی را عوض نمی‌کند: کف برنده است، و همین چت را، هر چه تنظیم کنید، زیر سقف تلگرام نگه می‌دارد.

کارت یک کار طولانی کمتر آپدیت می‌شود#

سرعت بالا برای دو دقیقهٔ اول یک کار است. بعد از آن، هرچه کار قدیمی‌تر شود کارت کندتر می‌شود، و از ۱۰ دقیقه به بعد ساعتش ۳۰ ثانیه ۳۰ ثانیه جلو می‌رود، هم‌پای آپدیت‌ها، تا هیچ‌وقت هنگ‌کرده به نظر نرسد:

سن کارکارت حداکثر هر چند وقت آپدیت می‌شودساعت کارت
۰ تا ۲ دقیقهمثل بالا (برای یک کارت در چت خصوصی حدود ۴٫۸ ثانیه)۰:۴۵
۲ تا ۱۰ دقیقه۱۰ ثانیه۴:۱۰
۱۰ تا ۶۰ دقیقه۳۰ ثانیه۲۳:۰۰، ۲۳:۳۰
بیشتر از ۶۰ دقیقه۳۰ ثانیه۱:۲۳:۰۰، ۱:۲۳:۳۰

ساعت به پلهٔ ۳۰ ثانیه‌ای پایین گرد می‌شود و آپدیت‌ها دست‌کم ۳۰ ثانیه، گاهی کمی بیشتر، از هم فاصله دارند. پس کارت گاهی یک پله را جا می‌اندازد: آپدیتی در ۲۳ دقیقه و ۲۹ ثانیه ۲۳:۰۰ را نشان می‌دهد، و اگر بعدی در ۲۴ دقیقه و ۱ ثانیه بیاید ۲۴:۰۰ را، پس ۲۳:۳۰ دیده نمی‌شود.

یک ردیف ابزار یا جملهٔ جدید منتظر آپدیت بعدی می‌ماند؛ تغییر وضعیت (سشنی که از کار کردن به انتظار برای یک ایجنت پس‌زمینه می‌رود، و برعکس) فوراً دیده می‌شود، حداکثر هر ۱۰ ثانیه یک بار. ردیف‌های زندهٔ ایجنت‌ها و خط انتظار هم همین پله‌ها را دارند. کارت تمام‌شده مدت کار را با ثانیه‌های واقعی نشان می‌دهد (۲۳:۱۷).

همین جلوی این را می‌گیرد که یک کار چهارساعته یک پیام را هزاران بار ویرایش کند: در ۲۰۲۶-۰۹-۲۳ یک کارت دقیقاً همین کار را کرد و چت هفت ساعت بن شد. برای اینکه سرعت بالا در کل کار بماند، ‎/settings ← ⏱ آپدیت کارت در کار طولانی را خاموش کنید (برای کل چت، یا برای یک سشن از Mini App یا 👤 تنظیمات هر سشن).

حباب «در حال تایپ…»#

حباب «در حال تایپ…» را یک حلقه برای هر چت می‌فرستد، هر چند سشن که در آن کار کنند (در همهٔ برنامه‌های تلگرام حباب برای کل چت است)، هر TYPING_INDICATOR_INTERVAL ثانیه (پیش‌فرض ۴٫۵؛ تلگرام وضعیت تایپ را بعد از ۵ ثانیه پاک می‌کند؛ 0 حباب را خاموش می‌کند). در سهمیهٔ چت، کم‌اهمیت‌ترین چیزی است که چت می‌فرستد:

  • هرچه کار قدیمی‌تر شود کندتر می‌شود، بر اساس سن قدیمی‌ترین کار در حال اجرای چت: در ده دقیقهٔ اول هر ۴٫۵ ثانیه (حبابی ثابت)، بعد از آن هر ۱۵ ثانیه؛ تلگرام آن را ۵ ثانیه نشان می‌دهد، پس حباب یک کار قدیمی‌تر چشمک می‌زند و ثابت نمی‌ماند. با ۴٫۵ ثانیه، حباب به‌تنهایی ۸۰۰ درخواست در ساعت می‌شد و سقف ساعتی (پایین) آن را برای مدت‌های طولانی خاموش می‌کرد؛ خاموش کردن ⏱ آپدیت کارت در کار طولانی آن را روی ۴٫۵ ثانیه نگه می‌دارد؛
  • از شروع هر کار دیده می‌شود؛ کارتِ کاری که تازه شروع شده کمی کندتر آپدیت می‌شود تا جا باز شود: سهم حباب از چت قبل از اینکه کارت‌ها بقیه را تقسیم کنند کنار گذاشته می‌شود (بالا)، پس این دو روی هم هیچ‌وقت از سقف‌های چت رد نمی‌شوند؛
  • هیچ‌وقت سهمی را که یک ویرایش کارت لازم دارد نمی‌گیرد: حبابی که درست بعد از ویرایش یک کارت نوبتش باشد نیم ثانیه صبر می‌کند (TYPING_RETRY_WAKE) و دوباره امتحان می‌کند، پس حداکثر یکی دو ثانیه دیر می‌شود، هیچ‌وقت جا نمی‌افتد؛
  • وقتی حجم ساعتی چت بالا برود، اولین چیزی است که حذف می‌شود (پایین)؛
  • یک 429 روی خود حباب فقط جلوی حباب را، به اندازه‌ای که تلگرام خواسته، می‌گیرد (کارت‌ها ادامه می‌دهند)، ولی دورهٔ شش‌ساعتهٔ هشدار چت را شروع می‌کند (سرعت به ۰٫۵ درخواست در ثانیه محدود می‌شود، پس کارت‌ها هم کند می‌شوند)؛
  • یک بن روی حباب (یک retry_after بیشتر از سقفی که پایین آمده) چت را درست مثل بن روی هر درخواست دیگری ساکت می‌کند: دیگر چیزی به آن فرستاده نمی‌شود، و جواب کار نگه داشته می‌شود و وقتی بن تمام شد می‌رسد.

قبلاً مجانی بود (یک حلقه برای هر سشن در حال کار، بیرون از هر سهمیه‌ای)، تا اینکه در ۲۰۲۶-۰۹-۲۳ دو سشن در یک چت خصوصی در سه ساعت حدود ۵۴۰۰ بار آن را فرستادند و تلگرام خود حباب را محدود کرد.

ربات کند شد: محدودیت سرعت (429)#

اگر تلگرام باز هم سرعت یک چت را محدود کند، به یک درخواست با 429 و یک retry_after چندثانیه‌ای جواب می‌دهد. aipager دقیقاً همان مدت به آن چت درخواستی نمی‌فرستد، بعد همان یک ارسال عقب‌افتاده را دوباره انجام می‌دهد، و فاصلهٔ آپدیت کارت‌های آن چت را دو برابر می‌کند (تا ×۸). هر دقیقهٔ آرام آن را نصف می‌کند تا به حالت عادی برگردد.

آنچه می‌بینید:

  • ‏aipager status (و ردیف aipager daemon در aipager doctor) Telegram flood backoff ×4 (chat …), last 429 12 s ago را نشان می‌دهد.
  • دقیقاً یک خط در aipager logs، بدون traceback:‏ flood: chat … 429 retry_after=5s → cadence ×2.
  • چیزی ساکت نمی‌شود و هیچ جوابی از دست نمی‌رود: عقب می‌افتد، حذف نمی‌شود.
  • سرعتی که چت به دست آورده نصف می‌شود و چت وارد یک دورهٔ هشدار شش‌ساعته می‌شود (FLOOD_WARNING_HOURS): سرعتش نمی‌تواند از ۰٫۵ درخواست در ثانیه (FLOOD_WARNED_CEILING) بالاتر برود و آهسته بالا می‌رود. aipager status نشانش می‌دهد: Telegram chat 123: rate 0.25/s (ceiling 0.50/s), 212/1200 calls in the last hour (as of 18s ago), 7/30 in the last minute - warning regime, 5h 52m left.

لازم نیست کاری بکنید. خودش درست می‌شود. خط backoff بعد از یکی دو دقیقه آرامی چت ناپدید می‌شود؛ سرعت در هر بازهٔ آرام ۰٫۱ درخواست در ثانیه بالا می‌رود (معمولاً یک دقیقه، در دورهٔ هشدار ۳۶ دقیقه) و سقف کامل وقتی دوره تمام شود برمی‌گردد. aipager doctor ردیف aipager را در تمام این مدت سبز نگه می‌دارد: چتی که سرعتش را کم کرده یعنی کار عادی. (قبلاً یک 429 در حدود پنج دقیقه بخشیده می‌شد. تنها هشدار تلگرام قبل از بن ۲۰۲۶-۰۹-۲۳ سه ساعت و ۲۳ دقیقه زودتر آمده بود، و چت چند دقیقه بعد از آن با سرعت کامل کار می‌کرد.)

سهمیهٔ ساعتی#

هر چت یک ساعت چرخان هم دارد: حداکثر FLOOD_HOURLY_MAX (۱۲۰۰) درخواست در هر ۶۰ دقیقه؛ حباب‌های تایپ، ویرایش کارت‌ها و جواب‌ها همه با هم؛ فقط ری‌اکشن‌ها حساب نمی‌شوند. ۱۲۰ درخواست آخر (FLOOD_HOURLY_ESSENTIAL_RESERVE) برای جواب‌ها، پاسخ‌ها و درخواست‌ها نگه داشته می‌شود:

  • با ۸۱۰ درخواست در آن ساعت، حباب تایپ متوقف می‌شود (زیر ۶۴۸ برمی‌گردد)؛
  • با ۱۰۸۰، چت وارد مود حداقلی (پایین) می‌شود تا ساعت به ۸۶۴ برسد؛
  • جواب‌ها هیچ‌وقت به خاطر سهمیهٔ ساعتی رد نمی‌شوند؛ اگر روزی از ۱۲۰۰ بگذرند، لاگ ساعتی یک بار این را می‌گوید.

‏aipager status درخواست‌های ساعت گذشتهٔ چت را کنار سهمیه‌اش نشان می‌دهد. این عدد از فایل وضعیتی می‌آید که aipager تا وقتی درخواست‌ها جریان دارند حداکثر دقیقه‌ای یک بار بازنویسی می‌کند، پس سنش هم کنارش نوشته می‌شود. دو سشن شلوغ که ساعت‌ها در یک چت خصوصی متن می‌فرستند خیلی زیر سهمیه می‌مانند (اتفاق ۲۰۲۶-۰۹-۲۳ وقتی دوباره اجرا شد: حدود ۹۰۰ درخواست در شلوغ‌ترین ساعت، در برابر حدود ۳۴۰۰ برای همان کار بدون این سهمیه).

سرعت به‌دست‌آمده، و چرا ممکن است کارت‌هایتان از قبل کندتر باشند#

از نسخهٔ 0.7.13، سرعت پایدار ارسال هر چت یاد گرفته می‌شود، نه فرض. تلگرام سقفی را که واقعاً روی ربات شما اعمال می‌شود منتشر نمی‌کند (به تاریخچهٔ اخیر حسابتان بستگی دارد)، پس aipager هر چت را با ۰٫۵ درخواست در ثانیه شروع می‌کند، برای هر دقیقهٔ آرام ۰٫۱ اضافه می‌کند تا سقف ۱ در ثانیه، با یک 429 نصفش می‌کند و بعد از یک بن به ۰٫۰۵ پایین می‌آوردش. پس رباتی که تازه بن شده خیلی محتاط‌تر از رباتی که نشده جلو می‌رود، و سرعتش را در ساعت‌های بعد دوباره به دست می‌آورد.

اگر سرعت یک چت زیر ۰٫۲ درخواست در ثانیه برود (یا سهم کارت‌ها و حباب از سهمیهٔ ساعتی‌اش تمام شود)، وارد مود حداقلی می‌شود: کارت‌های در حال کار دیگر انیمیشن ندارند و یک خط ثابت ⏳ x1 · در حال کار (کارت فعلاً آپدیت نمی‌شود) نشان می‌دهند، حباب تایپ متوقف می‌شود، و نوار وضعیت سنجاق‌شده ⏸ کارت‌ها فعلاً آپدیت نمی‌شوند (سقف ساعتی Telegram) (یا وقتی خود سرعت چت را به این مود برده، ⏸ کارت‌ها فعلاً آپدیت نمی‌شوند (محدودیت Telegram)) را نشان می‌دهد و بقیه‌اش تا تمام شدن این مود عوض نمی‌شود. جواب‌ها، پاسخ‌ها و درخواست‌های اجازه همچنان می‌رسند؛ هدف همین است. کارت حدود ۹۵٪ چیزی است که این ربات می‌فرستد و جواب حدود ۵٪، پس زیر فشار، ظاهر را فدا می‌کند نه کار را. aipager doctor مود حداقلی را به‌شکل هشدار گزارش می‌دهد تا یک کارت متوقف هیچ‌وقت با یک کارت خراب اشتباه گرفته نشود؛ وقتی سرعت برگردد، خودش تمام می‌شود.

ربات ساکت شد: بن تلگرام (flood control)#

یک retry_after بیشتر از TELEGRAM_MAX_RETRY_AFTER (پیش‌فرض ۹۰ ثانیه) محدودیت سرعت نیست؛ یک بن است و می‌تواند ساعت‌ها طول بکشد. از داخل چت به نظر می‌رسد ربات مرده: پیام‌ها هنوز به Claude می‌رسند، سشن‌ها کار می‌کنند، ولی جوابی برنمی‌گردد.

آنچه می‌بینید:

  • ‏aipager status (و ردیف aipager daemon در aipager doctor) Telegram flood-muted until HH:MM (chat …) را نشان می‌دهد.
  • یک خط در aipager logs:‏ Telegram flood control — chat … muted for Ns (until HH:MM) …‎، بعد سکوت برای آن چت. بعداً یک خط flood mute on chat … lifted.
  • ‏aipager status وضعیت کامل چت را هم نشان می‌دهد: Telegram chat 123: rate 0.05/s (ceiling 0.50/s), 431/600 calls in the last hour (as of 12s ago) - MINIMAL MODE, card updates paused - flood-muted until 09:41 - warning regime, 5h 59m left (1 ban(s) in the last 7 days).

‏aipager چت را دقیقاً همان مدتی که تلگرام خواسته ساکت می‌کند و هیچ درخواستی از هیچ نوع به آن نمی‌فرستد: جواب‌ها، ویرایش کارت‌ها، پیوست‌ها، ری‌اکشن‌ها، نشانگر تایپ، پیام‌های کوچک بعد از زدن دکمه، و جواب‌هایی که فرمان‌هایتان می‌گرفتند. هر کدام یک تخلف جدید بود که بن را طولانی‌تر می‌کرد؛ یک درخواست وسط بن فعال همان چیزی بود که در ۲۰۲۶-۰۹-۱۵ یک بن ۲۱ دقیقه‌ای را به ۹٫۵ ساعت رساند. پس فرمانی که وسط سکوت تایپ شود هیچ جوابی نمی‌گیرد، و زدن دکمه هم تأییدی نمی‌گیرد؛ تا نسخهٔ 0.7.12 پیام کوچک بعد از دکمه هنوز فرستاده می‌شد، با این فرض که تلگرام آن را جدا حساب می‌کند. برای کم کردن سرعت جدا حساب می‌کند، برای بن نه. بقیهٔ چت‌ها تحت تأثیر نیستند.

پیام دادن به ربات وسط بن بی‌خطر است و چیزی از دست نمی‌رود. هیچ کاری که در چت بکنید باعث نمی‌شود ربات وقتی چت ساکت است به تلگرام درخواست بفرستد، پس نمی‌تواند بن را طولانی‌تر کند:

  • پیامی که می‌فرستید (متن، ویس، فایل، یک قالب آماده) باز هم به Claude می‌رسد و سشن رویش کار می‌کند. کارت در حال کارش نگه داشته می‌شود، دور ریخته نمی‌شود: اگر وقتی بن تمام می‌شود کار هنوز در جریان باشد، کارت همان موقع می‌آید. بن، چت را تا مدتی بعد از خودش در مود حداقلی نگه می‌دارد، پس کارت ممکن است چند دقیقه دیرتر از تمام شدن خود بن بیاید. اگر کار وسط بن تمام شده باشد، جوابش را می‌گیرید و کارتی نمی‌آید.
  • 🔄 دوباره امتحان کن وسط بن کاری نمی‌کند. پیام دوباره فرستاده نمی‌شود و دکمه سر جایش می‌ماند، تا بعد از بن دوباره بزنیدش. تا خود نسخهٔ 0.7.14، پیام به Claude می‌رسید ولی پیام خطا و دکمه‌اش می‌ماندند، پس زدن دوباره آن را دوباره می‌فرستاد.
  • کیبورد اصلی هم نگه داشته می‌شود، از جمله کیبوردی که ری‌استارت می‌فرستد (تا خود نسخهٔ 0.7.14 گم می‌شد تا چیز دیگری آپدیتش کند). بعد از تمام شدن بن فرستاده می‌شود.

بعد از تمام شدن بن، چیزها به این ترتیب می‌رسند: جواب‌های نگه‌داشته‌شده، بعد کارت کارهایی که هنوز در جریان‌اند، بعد کیبورد. کارتی که باید تا تمام شدن مود حداقلی صبر کند بعد از کیبورد می‌آید.

جواب‌ها از دست نمی‌روند. جوابی که وقتی چت ساکت است آماده شود نگه داشته می‌شود و بعد از تمام شدن بن، در چند ثانیه، با خط اولی مثل ⏳ دیر رسید: ۴۲ دقیقه پشت محدودیت Telegram ماند می‌رسد. لازم نیست دوباره بپرسید؛ و اگر دوباره پرسیدید، هر دو جواب می‌رسند، اول قدیمی‌تر: بنی که ساعت‌ها طول بکشد چند کار را در بر می‌گیرد و جواب هر کدام مال شماست. (جواب‌های نگه‌داشته‌شده در حافظه‌اند: اگر aipager را وقتی چند جواب منتظرند ری‌استارت کنید، از دست می‌روند و لاگ خاموش شدن می‌گوید چندتا. یک چت حداکثر ۲۰ جواب نگه می‌دارد و هیچ‌کدام قدیمی‌تر از ۲۴ ساعت نیست؛ هر چیزی که به یکی از این دو دلیل کنار برود به‌شکل هشداری در لاگ می‌آید که می‌گوید چه بود.)

بن، چت را بعدش کندتر می‌کند، نه سریع‌تر. همان لحظه که بن شروع می‌شود، سرعت یادگرفته‌شدهٔ چت به کف می‌رسد و بن شمرده می‌شود؛ ساعت‌های سکوت چیزی برنمی‌گردانند، بالا رفتن از لحظهٔ تمام شدن بن از نو شروع می‌شود، و تا هفت روز (FLOOD_BAN_MEMORY_DAYS) سقف سرعت چت و سهمیهٔ ساعتی‌اش بر یک به‌علاوهٔ تعداد بن‌های آن هفته تقسیم می‌شوند: یک بن هر دو را نصف می‌کند، دو بن یک‌سوم. aipager status همه را نشان می‌دهد. (این حافظه قبلاً ۲۴ ساعت بود و فقط سقف را نصف می‌کرد؛ چتی که در ۲۰۲۶-۰۹-۱۹ بن شده بود در ۲۰۲۶-۰۹-۲۳ با سرعت کامل کار می‌کرد، و هفت ساعت بن شد.) پنج بن یا بیشتر در یک هفته چت را تا وقتی آن بن‌ها کهنه شوند در مود حداقلی نگه می‌دارد: جواب‌ها همچنان می‌رسند، کارت‌ها ثابت می‌مانند.

کارهایی که نباید بکنید:

  • برای «درست کردن» بن، aipager را ری‌استارت نکنید. سکوت در همان ساعتی که نشان داده شده خودش تمام می‌شود. از نسخهٔ 0.7.13، ری‌استارت دیگر بن را فراموش نمی‌کند (مهلت، سرعت به‌دست‌آمدهٔ چت و تاریخچهٔ بن‌هایش در ‎~/.claude/aipager-flood-state.json ذخیره و در شروع برگردانده می‌شوند، و همین‌طور درخواست‌های ساعت آخر چت و دورهٔ هشدارش)، پس ری‌استارت دیگر بن را طولانی‌تر هم نمی‌کند. ولی جواب‌هایی را که هنوز نگه داشته شده‌اند دور می‌ریزد و چیزی را درست نمی‌کند.
  • ‏TELEGRAM_MAX_RETRY_AFTER را به امید زودتر امتحان کردن پایین‌تر از ۹۰ ثانیهٔ پیش‌فرض نیاورید: هر چیزی بیشتر از این سقف بن است، نه محدودیت سرعت.

برای پیشگیری: سشن‌های همزمان کمتری در هر چت اجرا کنید، یا پرکارترین‌ها را به یک چت جدا ببرید (aipager config).

یک سشن از نوار وضعیت سنجاق‌شده بیرون افتاد (GONE است)#

پروسهٔ dtach آن سشن بسته شده (ری‌استارت کامپیوتر، pkill claude، کسی در سشن وصل‌شده به dtach exit تایپ کرده). از اول بسازیدش؛ پوشهٔ ‎~/.claude/projects/...‎ آن هنوز گفتگو را دارد:

ساده‌ترین راه، ‎/resume <label>‎ در تلگرام است (یا ‎/resume خالی برای یک فهرست انتخاب): سشن را دوباره اجرا می‌کند و گفتگو را از همان‌جا ادامه می‌دهد. از خط فرمان:

sh
aipager resume <label>             # همان کار، از ترمینال
aipager session <label>            # یا یک سشن جدید، بدون تاریخچه
aipager session <label> --continue # dtach جدید، آخرین گفتگوی همان پوشه

درخواست اجازه‌ای که ۵ دقیقه بی‌خبر مانده#

اگر سشنی منتظر یک درخواست اجازه یا سؤال است و Claude Code ۵ دقیقه هیچ خبری نمی‌دهد، aipager گفتگوی ذخیره‌شدهٔ سشن را می‌خواند. فقط خبرهای خود Claude و ایجنتی که پرسیده حساب می‌شود: ایجنت پس‌زمینه‌ای که به کارش ادامه می‌دهد جلوی این بررسی را نمی‌گیرد. فقط اگر گفتگو نشان بدهد درخواست تمام شده (در ترمینال جوابش داده شده و خبرش گم شده)، aipager دیگر منتظر آن درخواست نمی‌ماند و سشن را دوباره در حال کار حساب می‌کند. وگرنه درخواست هر چقدر طول بکشد باز می‌ماند: کارت و نوار سنجاق‌شده همچنان می‌گویند سشن منتظر جواب شماست، یادداشت «هنوز در حال کار» فرستاده نمی‌شود، و پیام‌هایتان تا وقتی جواب بدهید نگه داشته می‌شوند (متن را ببینید). اگر Claude Code با درخواست باز بسته شود، سشن تمام می‌شود. اگر آن پنجرهٔ سؤال هنوز باز باشد، دکمه‌های درخواست هنوز جوابش را می‌دهند (جواب‌ها را ببینید).

عوض کردن این انتظار:

sh
AIPAGER_INTERACTIVE_TIMEOUT=300 aipager start    # به ثانیه

قابلیت ویس از تلگرام نصب نمی‌شود#

دکمهٔ [📦 نصب قابلیت ویس] نصب‌کننده را اجرا می‌کند و تا وقتی کار می‌کند هر چند ثانیه پیامش را ویرایش می‌کند (📦 در حال نصب قابلیت ویس - هنوز ادامه دارد… (۲۵ ثانیه)). اگر نصب شکست بخورد، پیام کد خروج و ۵۰۰ حرف آخر خروجی نصب‌کننده را نشان می‌دهد. دلیل‌های رایج:

  • شبکه: pip به PyPI نمی‌رسد. اتصال را از کامپیوتری که aipager رویش اجرا می‌شود چک کنید.
  • دیسک: ‎~/.cache/huggingface/‎ حدود ۷۴ مگابایت برای مدل لازم دارد و حافظهٔ wheel مربوط به pip حدود ۲۵۰ مگابایت دیگر. اول جا باز کنید.
  • ‏Permission denied:‏ venv فقط‌خواندنی است. به uv tool install بروید که همیشه venvی مال خود کاربر به کار می‌برد.

اگر ربات وسط نصب ارتباطش را از دست داد، خود نصب معمولاً روی کامپیوتر تمام شده: aipager را ری‌استارت کنید و دوباره یک ویس امتحان کنید.

باز کردن اپ می‌گوید «برای ورود، این صفحه را از برنامهٔ Telegram باز کنید.»#

صفحه لود شد، ولی اسکریپت Mini App تلگرام (همان که initData را می‌سازد) لود نشد، پس صفحه چیزی برای ورود ندارد و هیچ درخواستی به API نمی‌فرستد. پیام تقصیر را گردن شما می‌اندازد؛ دلیلش شبکه است.

نسخه‌های اخیر aipager آن اسکریپت را خودشان دانلود می‌کنند و از آدرس خود صفحه (‎/telegram-web-app.js) سرو می‌کنند، پس گوشی فقط باید به همان جایی برسد که صفحه را داده، نه به telegram.org هم. اگر این را در یک نسخهٔ قدیمی‌تر می‌بینید، آپدیت کنید.

بعد، به ترتیب:

  1. سورس صفحه را نگاه کنید. اگر تگ ‎<script>‎ آن به https://telegram.org/js/telegram-web-app.js اشاره می‌کند، aipager هنوز نتوانسته اسکریپت را دانلود کند و صفحه دارد آن را از خود تلگرام لود می‌کند، و این همان حالتی است که روی گوشی‌ای که به telegram.org نمی‌رسد شکست می‌خورد. aipager اسکریپت را وقتی سرور Mini App شروع می‌شود دانلود می‌کند و حداکثر روزی یک بار دوباره امتحان می‌کند، پس ری‌استارت aipager فوراً دوباره امتحان می‌کند؛ journalctl --user -u aipager | grep "webapp sdk"‎ می‌گوید چه چیزی خراب شد (معمولاً یک telegram.org بسته یا فیلترشده).
  2. اگر تگ به ‎/telegram-web-app.js اشاره می‌کند، چک کنید aipager آن را سرو می‌کند: curl -sI http://127.0.0.1:8765/telegram-web-app.js روی کامپیوتر aipager باید با 200 و Content-Type: application/javascript جواب بدهد (اگر پورت را عوض کرده‌اید، تنظیمش کنید). نسخهٔ آن زیر ‎~/.local/share/aipager/webapp-sdk/‎ است.
  3. آدرس را به جای دکمهٔ ‎/app یا دکمهٔ منوی ربات، در یک مرورگر معمولی باز کرده‌اید: پیام همین را باید بگوید. SDK فقط داخل تلگرام initData می‌سازد.
  4. صفحه بیشتر از پنج دقیقه باز مانده: initData منقضی می‌شود و صفحه می‌خواهد دوباره باز شود. دوباره ‎/app را بزنید.
  5. ‏‎📱 App را روی کیبوردی از نسخهٔ قدیمی‌تر aipager زده‌اید. تلگرام به Mini Appی که از دکمهٔ کیبورد باز شود initData نمی‌دهد، برای همین کیبورد aipager دیگر این دکمه را ندارد. ‎/start را بفرستید تا کیبورد جدید بیاید، و اپ را از دکمهٔ منو یا با ‎/app باز کنید.

pyexpat _XML_SetAllocTrackerActivationThreshold موقع نصب با brew#

بستهٔ python@3.12 هوم‌برو با libexpat جدیدتری از آنچه سیستم شما دارد ساخته شده؛ تقریباً همیشه به این دلیل که روی macOS Tahoe (26.x) Xcode و Command Line Tools قدیمی‌اند. خروجی خود brew معمولاً همین را می‌گوید. دو راه:

  • به جایش uv tool install aipager را به کار ببرید. uv پایتون خودش را همراه دارد و کلاً از این مشکل دور می‌ماند. این راه پیشنهادی روی macOS است؛ README را ببینید.

  • ‏Xcode و Command Line Tools را آپدیت کنید:

    sh
    sudo rm -rf /Library/Developer/CommandLineTools
    sudo xcode-select --install
    

    یا Xcode را در App Store باز کنید و آن را به آخرین نسخه آپدیت کنید.

«ModuleNotFoundError: aipager»#

فایل اجرایی aipager به Pythonی اشاره می‌کند که دیگر aipager را ندارد (معمولاً بعد از پاک شدن یک venv). دوباره نصب کنید:

sh
uv tool install --reinstall aipager
# یا با هر نصب‌کننده‌ای که اول استفاده کردید: pipx، brew، pip

فهرست سشن‌ها گم شد یا خراب شد#

‏aipager سشن‌هایش را در ‎~/.claude/aipager-sessions.json نگه می‌دارد و آن را به‌شکل اتمی بازنویسی می‌کند (یک فایل جدید، بعد تغییر اسم)، پس نوشتنی که نیمه‌کاره بماند فایل قبلی را سالم می‌گذارد. اگر فایل با این حال نباشد، خوانده نشود یا JSON معتبر نباشد، aipager در لاگ می‌نویسد که از نو شروع می‌کند (اگر فایل بوده ولی خوانده نشده، به‌شکل هشدار) و با فهرست خالی شروع می‌کند؛ متوقف نمی‌شود. از این فایل نسخهٔ پشتیبانی نیست. چیز مهمی از دست نمی‌رود:

  • سشن‌های در حال اجرا در اولین تیک ناظر، از روی سوکت‌های dtach‌شان (‎/tmp/claude-dtach-*.sock)، دوباره پیدا می‌شوند؛
  • همهٔ گفتگوها هنوز در پوشهٔ ‎~/.claude/projects/...‎ خود Claude Code هستند، پس aipager session <name> --continue در پوشهٔ همان سشن ادامه‌شان می‌دهد (‎--resume اجازه می‌دهد یکی را انتخاب کنید)؛
  • آنچه از دست می‌رود فهرست سشن‌های بسته‌شده (‎/resume)، کارت‌هایی که باز بودند، و بقیهٔ چیزهایی است که aipager دربارهٔ هر سشن یادش بود.

اگر aipager مدام موقع شروع شکست می‌خورد، aipager logs (یا journalctl --user -u aipager) دلیلش را نشان می‌دهد؛ فایل را کنار بگذارید (mv ~/.claude/aipager-sessions.json ~/aipager-sessions.json.old) تا مطمئن شوید مشکل از آن نیست.

شروع یک سشن شکست می‌خورد#

شروعی که dtach ردش کند، دلیلش را در یک خط در چت نشان می‌دهد (سوکت از قبل هست، shell قابل اجرا نیست، ترمینال مجازی در دسترس نیست، اسم زیادی طولانی است، اجازهٔ دسترسی نیست، پوشه وجود ندارد)؛ پیام خود dtach، با مسیرهایش، در aipager logs است.

فهرست بررسی‌های aipager doctor#

ترتیب مهم است: هر بررسی بعدی فرض می‌کند قبلی‌ها رد شده‌اند. بررسی‌ای که در یک محیط غیرمنتظره کرش کند، به‌شکل یک ردیف ⚠ با اسم بررسی و خطا نشان داده می‌شود؛ بقیهٔ بررسی‌ها باز هم اجرا می‌شوند.

بررسی (کلید ‎--json)چه چیزی را چک می‌کندراه‌حل
config_parsesaipager.yaml و policy.yaml خوانده می‌شوند؛ اول اجرا می‌شود، چون همهٔ بررسی‌های بعدی تنظیمات را می‌خوانندخطا فایل و خط را نام می‌برد
config‎~/.config/aipager/aipager.yaml وجود دارد و توکن و چت داردaipager config
token_validتوکن با getMe تلگرام کار می‌کنددوباره aipager config
chat_reachableتلگرام چت تنظیم‌شده را می‌شناسد (getChat؛ چیزی فرستاده نمی‌شود)ربات را باز کنید و Start را بزنید
teamچت‌ها و اعضا (یا یک team.yaml قدیمی): می‌گوید استفادهٔ شخصی است یا تیمی، و یک team.yaml قدیمی خراب یا ناجور را نشان می‌دهدaipager config
role_shell_accessبرای هر نقشی که عضوی دارد و می‌تواند Bash اجرا کند یک بار هشدار می‌دهد (قانون‌های ایمنی‌اش در حد تلاش است، نه یک مرز؛ استفادهٔ تیمی را ببینید)در policy.yaml به آن نقش Bash ندهید، یا قبولش کنید
peer_messagesپیام‌های بین سشن‌های Claude: رسیدهایشان کجا نگه داشته می‌شود و آن پوشه خصوصی است یا نه، این سیستم می‌تواند زمان شروع فرستنده را چک کند یا نه، و یک هشدار برای هر نقشی که یک policy به آن اجازهٔ SendMessage داده (مدل امنیتی را ببینید)پوشهٔ رسیدی را که مشترک شده پاک کنید (aipager دوباره می‌سازدش)، یا به آن نقش SendMessage ندهید
claudeفایل اجرایی claude را همان‌طور که هر شروع سشن پیدا می‌کند پیدا می‌کند (claude_path در aipager.yaml یا ‎$AIPAGER_CLAUDE_BIN بی‌چون‌وچرا برنده‌اند؛ وگرنه جدیدترین نسخه بین ‎~/.local/bin،‏ PATH و Homebrew)، و هر نصب جداگانهٔ دیگری را که پیدا شد فهرست می‌کندClaude Code را نصب کنید، یا claude_path /‏ AIPAGER_CLAUDE_BIN را تنظیم کنید
claude_authclaude auth status را در همان محیطی که یک سشن واقعی می‌گیرد اجرا می‌کند. هیچ‌وقت FAIL نمی‌شود: «لاگین نیست» و «خود بررسی شکست خورد» جدا از هم گزارش می‌شوند و هیچ‌کدام جلوی شروع سشن را نمی‌گیردclaude auth login، یا یک کلید API یا CLAUDE_CODE_OAUTH_TOKEN تنظیم کنید
dtachفایل اجرایی dtach پیدا شد (dtach-bin خود aipager، یا یکی در PATH)uv tool install --reinstall aipager
hook_scriptsaipager-hook و aipager-statusline در PATH هستندuv tool install --reinstall aipager
settings_jsonهوک‌های aipager در ‎~/.claude/settings.json وصل شده‌اندaipager config
daemonaipager اجرا می‌شود و سوکتش جواب می‌دهد؛ وضعیت محدودیت سرعت تلگرام را هم نشان می‌دهد (بالا را ببینید)aipager start
service_installedاختیاری: فایل سرویس وجود داردaipager service install
service_unit_pathفقط Linux:‏ Environment=PATH=‎ در فایل سرویس نصب‌شده واقعاً پوشهٔ فایل اجرایی claude را دارد؛ به‌شکل متن خوانده می‌شود، چون doctor نمی‌تواند PATH خود systemd را از shell تعاملی شما ببیندaipager service install --yes
miniappوقتی Mini App روشن است، می‌تواند شروع شود یا نه. هیچ‌وقت FAIL نمی‌شود: Mini App اختیاری استراه‌حلی که خودش نام می‌برد

‏aipager doctor --json همین بررسی‌ها را، به همین ترتیب، با همین کلیدها چاپ می‌کند (فرمان‌ها را ببینید).

‏aipager doctor --fix را اجرا کنید تا به‌شکل تعاملی یک اطلاعات ورود Claude را پیدا کند و در daemon.env کپی کند (همین‌طور وقتی فایل هست ولی چیزی ندارد)، یا وقتی بیش از یک نصب پیدا شده claude_path را ثابت کند. همیشه فقط بعد از پرسیدن کاری می‌کند. برای فایل سرویسی که PATH آن پوشهٔ claude را ندارد، aipager service install --yes را اجرا کنید.

aipager claude را پیدا نمی‌کند، یا نصب اشتباه را انتخاب می‌کند#

قبلاً شش جای مختلف claude را جداگانه پیدا می‌کردند و ممکن بود با هم فرق کنند. حالا همه از یک پیداکننده (aipager/claude_resolve.py) می‌گذرند. claude_path در aipager.yaml، و بعد ‎$AIPAGER_CLAUDE_BIN، وقتی کار کنند بی‌چون‌وچرا برنده‌اند. وگرنه هر claude که در ‎~/.local/bin، در ‎$PATH و در پوشه‌های Homebrew پیدا شود چک می‌شود و جدیدترین نسخه برنده است (پس جابه‌جا کردن ترتیب ‎$PATH، وقتی نصب دیگر جدیدتر است، انتخاب را عوض نمی‌کند). aipager doctor را اجرا کنید تا ببینید دقیقاً کدام را انتخاب کرده و چه چیزهای دیگری پیدا کرده؛ اگر نصب اشتباه برنده شده، نصب درست را ثابت کنید:

sh
aipager doctor --fix        # انتخاب تعاملی بین نصب‌های پیدا‌شده
# یا دستی:
echo 'claude_path: /home/you/.local/bin/claude' >> ~/.config/aipager/aipager.yaml

سشن‌ها زیر سرویس systemd لاگین نمی‌شوند، ولی claude در ترمینال خوب کار می‌کند#

سرویس‌های systemctl --user هیچ‌وقت ‎~/.bashrc یا ‎~/.profile را نمی‌خوانند، پس یک خط export CLAUDE_CODE_OAUTH_TOKEN=…‎ در آن‌ها هیچ‌وقت به aipager نمی‌رسد. به جایش، فایل سرویس از LoadCredential=‎ خود systemd استفاده می‌کند و ‎~/.config/aipager/daemon.env را می‌خواند: یک فایل ساده KEY=VALUE با حالت دسترسی 0600 که اولین بار که aipager service install را اجرا می‌کنید خودکار ساخته می‌شود (اگر یک config.env قدیمی توکن داشته باشد از آن کپی می‌شود، وگرنه یک بار از shell لاگین شما پیدا می‌شود، وگرنه با یک هشدار خالی می‌ماند). اگر هنوز خالی است، aipager doctor --fix وقتی بله بگویید دوباره همان جاها را می‌گردد و خطی را که پیدا می‌کند اضافه می‌کند و بقیهٔ خط‌های فایل را نگه می‌دارد؛ هیچ‌وقت توکن را چاپ نمی‌کند. یا خودتان خط را اضافه کنید:

sh
cat ~/.config/aipager/daemon.env          # ببینید چه چیزی هست (یا نیست)
echo 'CLAUDE_CODE_OAUTH_TOKEN=sk-...' >> ~/.config/aipager/daemon.env
chmod 600 ~/.config/aipager/daemon.env
aipager service stop && aipager service start

برای اینکه این فایل از چه چیزی محافظت می‌کند و از چه چیزی نه، مدل امنیتی ← اطلاعات ورود Claude را ببینید.

جای سوکت کنترل aipager عوض شد#

‏aipager doctor و aipager status قبلاً همیشه به ‎/tmp/aipager.sock نگاه می‌کردند. زیر سرویس systemd، سوکت کنترل حالا در ‎$XDG_RUNTIME_DIR/aipager.sock است (فقط وقتی ‎$XDG_RUNTIME_DIR تنظیم نشده به ‎/tmp برمی‌گردد: کانتینرها، WSL1، توزیع‌های حداقلی). فقط همین یک سوکت جابه‌جا شد؛ سوکت‌های dtach هر سشن (‎/tmp/claude-dtach-*.sock) تغییری نکرده‌اند. اگر جای مشخصی لازم دارید، با AIPAGER_SOCKET_PATH عوضش کنید.

‎/update می‌گوید ری‌استارت سشن‌ها را می‌بندد (KillMode)#

فایل‌های سرویسی که قبل از این نسخه نوشته شده‌اند خط KillMode=‎ ندارند، پس systemd از control-group استفاده می‌کند: متوقف یا ری‌استارت کردن aipager.service همهٔ سشن‌های Claude را که aipager شروع کرده می‌بندد. برای همین ‎/update نسخهٔ جدید را نصب می‌کند ولی aipager را ری‌استارت نمی‌کند و سشن‌هایی را که ری‌استارت می‌بست فهرست می‌کند. یک بار درستش کنید:

text
aipager service install

فایل سرویس را با KillMode=process بازنویسی می‌کند، systemd را دوباره لود می‌کند و aipager را ری‌استارت می‌کند، و همان ری‌استارت با تنظیم جدید انجام می‌شود. با systemctl --user show -p KillMode aipager.service چک کنید (KillMode=process). با این تنظیم، systemd در هر ری‌استارت برای سشن‌هایتان خط‌های «left-over process» در لاگ می‌نویسد؛ این عادی است.

aipager update نمی‌تواند uv یا pipx را پیدا کند#

‏aipager update نصب‌کننده را با مسیر کامل در PATH شما به‌علاوهٔ ‎~/.local/bin،‏ ‎~/.cargo/bin، پوشه‌های Homebrew،‏ ‎/usr/bin و ‎/bin پیدا می‌کند. اگر باز هم می‌گوید pipx را پیدا نکرد، نصب‌کننده‌ای که این aipager را ساخته دیگر نیست یا جای دیگری است؛ با ابزاری که دارید دوباره نصب کنید (pipx install --force aipager،‏ uv tool install --reinstall aipager).

آپدیت رد شد: editable یا نصبی که مال شما نیست#

‏‎/update و aipager update فقط نصبی را آپدیت می‌کنند که مال خود کاربر شماست و می‌تواند رویش بنویسد، از طریق همان نصب‌کننده‌ای که ساختش. برای این‌ها رد می‌کنند و دلیل را می‌گویند:

  • یک checkout قابل ویرایش (برای توسعه): با git pull آپدیتش کنید؛
  • نصب Nix،‏ Snap،‏ Docker یا پکیج سیستم‌عامل: از آپدیت خود آن سیستم استفاده کنید؛
  • نصبی که مال کاربر دیگری است (مثلاً یک venv مال root زیر ‎/opt): با همان کاربر آپدیتش کنید؛
  • نصبی که از یک پوشهٔ محلی ساخته شده (pipx install /path/to/aipager): can't update from here: it was installed from a local folder; update it from that folder. نسخهٔ جدید را در آن پوشه بیاورید و از آن دوباره نصب کنید، یا با pipx install --force aipager به PyPI بروید؛
  • نصبی که نصب‌کننده‌اش معلوم نیست (could not tell which installer owns this aipager): با uv tool install aipager یا pipx install aipager دوباره نصبش کنید.

آپدیت شکست خورد: unexpected argument '--refresh'#

‏aipager نسخهٔ 1.0.0 و قدیمی‌تر uv tool upgrade aipager --refresh را اجرا می‌کرد که هیچ نسخه‌ای از uv قبولش نمی‌کند، پس هر آپدیت نصب uv با error: unexpected argument '--refresh' found متوقف می‌شد و چیزی ری‌استارت نمی‌شد. نسخه‌های جدیدتر uv tool upgrade aipager را اجرا می‌کنند. برای یک بار رد شدن از این، از ترمینال همان کامپیوتر آپدیت کنید (aipager update در آن نسخه‌ها همین مشکل را دارد):

text
uv tool upgrade aipager
systemctl --user restart aipager.service

بدون سرویس (یا روی macOS)، aipager را همان‌طور که اجرایش کرده بودید ری‌استارت کنید.

آپدیت Claude Code: با npm در پوشه‌ای نصب شده که نمی‌توانید رویش بنویسید#

‏Claude Codeی که با sudo npm install -g نصب شده در پوشه‌ای است که فقط root می‌تواند عوضش کند (مثل ‎/usr/lib/node_modules)، پس claude update که با کاربر شما اجرا شود با global folder isn't writable شکست می‌خورد. ‎/update و Mini App نسخهٔ جدیدتر را با از اینجا نمی‌شود آپدیت کرد: installed with npm into a folder your user can't write to و بدون دکمه برایش نشان می‌دهند. یک بار claude install را با همان کاربری که aipager با آن اجرا می‌شود اجرا کنید: Claude Code را به نصب‌کنندهٔ خودش زیر پوشهٔ خانهٔ شما می‌برد که بدون sudo آپدیت می‌شود. بعد aipager را ری‌استارت کنید (systemctl --user restart aipager.service، یا همان‌طور که اجرایش کرده بودید): aipager در حال اجرا همان Claude Codeی را نگه می‌دارد که در شروع پیدا کرده، و بعد از ری‌استارت جدیدترینی را که پیدا کند برمی‌دارد. اگر claude_path در aipager.yaml (aipager doctor --fix می‌تواند تنظیمش کند) یا AIPAGER_CLAUDE_BIN به نصب npm اشاره می‌کند، اول آن را به ‎~/.local/bin/claude ببرید یا پاکش کنید، چون این دو همیشه برنده‌اند.

آپدیت شد، ولی نسخه عوض نشد#

نصب pipx که از یک آدرس git ساخته شده از همان منبع git آپدیت می‌شود، نه از PyPI. وقتی آن منبع چیز جدیدتری ندارد، ‎/update می‌گوید aipager روی A است - این نصب pipx از منبع git خودش آپدیت می‌شود و آنجا نسخهٔ جدیدتری نیست. نسخهٔ جدید را آنجا push یا انتخاب کنید، یا با pipx install --force aipager به PyPI بروید.

بدون سرویس، aipagerی که هیچ مدیر سرویسی ری‌استارتش نمی‌کند (aipager start در یک ترمینال یا tmux،‏ Docker،‏ launchd) آپدیت را نصب می‌کند اما تا وقتی ری‌استارت نشود با همان کد قدیمی کار می‌کند. آن وقت ‎/update می‌گوید aipager B نصب شده و منتظر ری‌استارت است (نسخهٔ در حال اجرا: A).، و هوک‌های Claude Code که در هر رویداد از نو شروع می‌شوند شاید همین حالا B را اجرا کنند: مالک یک اعلان می‌گیرد که آپدیت نیمه‌کاره مانده (دو دقیقه بعد از اینکه هوک‌ها اولین بار B را اجرا کردند، پس ری‌استارتی که درست بعد از نصب بیاید هیچ‌وقت آن را نشان نمی‌دهد، و وقتی هیچ کاری در چت خصوصی مالک در جریان نباشد). وقتی aipager با B اجرا شود، آن اعلان بدون دکمه‌اش به ✅ آپدیت aipager تمام شد: حالا aipager نسخهٔ B است. تبدیل می‌شود. روی 🔄 همین حالا ری‌استارت کن بزنید (در پیام آپدیت، در اعلان، یا در تنظیمات ← آپدیت در Mini App). aipager صبر می‌کند تا هیچ کاری در جریان نباشد، تمیز می‌ایستد و نسخهٔ جدید را درجا شروع می‌کند: همان پروسه در همان ترمینال، پنجرهٔ tmux یا کانتینر، با همان دستور و همان محیط.

اگر شروع درجا شکست بخورد، بعد از رفتن پروسهٔ قدیمی یک نسخهٔ جدا aipager را شروع می‌کند. آن وقت خروجی‌اش به‌جای ترمینال شما در لاگ ری‌استارت خودکار نوشته می‌شود (aipager.log در پوشهٔ همان نصب، یا ‎/tmp/aipager.log)، و اگر آن نسخه برنگردد، لاگ aipager دستوری را که باید اجرا کنید می‌گوید. اگر خود مفسر از بین رفته باشد (محیطش پاک شده باشد)، یا هیچ چیزی شروع نشود، aipager با کد 1 خارج می‌شود، لاگ aipager با restart.failed:‎ و دستوری که باید اجرا کنید تمام می‌شود، و شروع بعدی آپدیت را اعلام می‌کند.

وقتی دکمهٔ همین حالا ری‌استارت کن نیست، پیام قدم‌های مخصوص راه‌اندازی شما را می‌دهد: در ترمینال یا tmux،‏ Ctrl+C را بزنید و aipager start را اجرا کنید؛ روی macOS،‏ launchctl kickstart -k gui/<uid>/com.aipager.daemon؛ در Docker،‏ docker restart <container>‎ روی میزبان. ساختن دوبارهٔ یک کانتینر Docker (docker compose up بعد از down، یا دوباره docker run) آن را از image خودش شروع می‌کند، و این نسخهٔ aipager داخل همان image را برمی‌گرداند: برای نگه داشتن aipager جدیدتر، از یک image جدیدتر استفاده کنید.

aipager بعد از آپدیت برنگشت#

آپدیت قبل از هر ری‌استارتی چک می‌کند نسخهٔ جدید import می‌شود، ولی اگر aipager جدید باز هم شروع نشود، systemd هر ۵ ثانیه دوباره امتحان می‌کند. دلیلش را ببینید:

text
journalctl --user -u aipager.service -n 50

نسخهٔ قبلی را با همان نصب‌کننده دوباره نصب کنید و بعد ری‌استارت کنید:

text
pipx install --force aipager==<previous>        # یا:
uv tool install --force aipager==<previous>     # یا:
<venv>/bin/python -m pip install aipager==<previous>
systemctl --user restart aipager.service

نصب pipx از یک مسیر محلی: pipx install --force /path/to/aipager روی commit قبلی. اگر یک اعلان قدیمی منتظر مانده، با rm -f ~/.local/share/aipager/update-restart.json پاکش کنید (در هر حال بعد از ۲۴ ساعت نادیده گرفته می‌شود)؛ ‎~/.local/share/aipager/update.lock فقط یک فایل قفل است و وقتی آپدیتی در جریان نیست پاک کردنش بی‌خطر است.

«An update was interrupted when aipager shut down»#

‏aipager وقتی ‎/update داشت نصب می‌کرد متوقف (یا ری‌استارت) شد و نصب‌کننده هم همراهش متوقف شد، پس ممکن است نصب نیمه‌کاره نوشته شده باشد. اگر aipager یا Claude Code درست کار نمی‌کند، تعمیرش کنید: برای aipager دستور نصب دوباره‌ای را که در پیام آمده اجرا کنید (مثلاً pipx install --force aipager) و بعد systemctl --user restart aipager.service؛ برای Claude Code دوباره claude update را اجرا کنید.

«همین حالا ری‌استارت کن»ی که نتوانسته aipager را دوباره شروع کند (بدون سرویس)، در لاگ aipager یک restart.failed:‎ همراه دستوری که باید اجرا کنید می‌گذارد؛ اجرایش کنید تا aipager جدید آپدیت را اعلام کند.

یک چت زبان اشتباهی دارد#

زبان aipager از چیزی می‌آید که برای آن چت انتخاب شده، نه از پیام‌های داخلش. در همان چت ‎/language را باز کنید و زبانی را که می‌خواهید انتخاب کنید: این انتخاب بر همه‌چیز مقدم است. در چت خصوصی، خودکار (زبان Telegram شما) دنبال زبان برنامهٔ تلگرامتان می‌رود (تنظیمات ← زبان در تلگرام)؛ زبانی که aipager ندارد انگلیسی خوانده می‌شود. چت خصوصی‌ای که قبل از اضافه شدن زبان‌ها وجود داشته تا شما انتخاب نکنید انگلیسی می‌ماند. یک گروه تا وقتی یک ادمین زبانش را انتخاب کند انگلیسی است. زبان فقط متن‌های خود aipager را عوض می‌کند: Claude به همان زبانی جواب می‌دهد که برایش می‌نویسید، هر چه aipager نشان دهد. زبان‌ها را ببینید.

توضیح ربات همانی نیست که من نوشتم#

‏aipager توضیح و توضیح کوتاه ربات را به هر زبانی که بلد است تنظیم می‌کند، برای کسانی که برنامهٔ تلگرامشان به آن زبان است، و تلگرام همین متن را به جای متنی که شما در BotFather نوشته‌اید به آن‌ها نشان می‌دهد. aipager این کار را فقط تا وقتی می‌کند که شما توضیح خودتان را ندارید، پس توضیحی که قبل از نصب این نسخه بنویسید به همه می‌رسد. اگر آن را بعد از اینکه aipager متن خودش را گذاشته نوشته‌اید، کسانی که به آن زبان‌ها هستند هنوز متن aipager را می‌بینند. برای اینکه متن شما را ببینند، متن aipager را برای هر زبان از طریق Bot API پاک کنید (setMyDescription و setMyShortDescription با متن خالی و همان language_code)؛ aipager تا وقتی متن شما آنجاست دیگر هیچ‌وقت آن را تنظیم نمی‌کند.

aipager می‌گوید از languages.json نمی‌شود استفاده کرد#

‏aipager چیزهایی را که دربارهٔ زبان‌ها یاد گرفته (چه کسانی قبل از اضافه شدن زبان‌ها اینجا بودند، آخرین زبان تلگرامی که از هر نفر دید، و اینکه پیشنهاد یک‌باره و خط اولین آشنایی فرستاده شده یا نه) در ‎~/.local/state/aipager/languages.json نگه می‌دارد. اگر این فایل خوانده نشود، aipager آن را در همان پوشه به languages.json.bad-<time>‎ کنار می‌گذارد، یک هشدار در لاگ می‌نویسد (و در هر شروع، تا شما تصمیم بگیرید، دوباره) و تا وقتی تصمیم بگیرید همهٔ چت‌ها را انگلیسی و بدون پیشنهاد زبان نگه می‌دارد: اگر می‌توانید فایل قدیمی را تعمیر کنید آن را برگردانید، یا languages.json را پاک کنید و ری‌استارت کنید، و aipager همهٔ کسانی را که می‌شناسد دوباره قدیمی حساب می‌کند (تا خودشان انتخاب کنند انگلیسی). زبانی که کسی انتخاب کرده در این فایل نیست و هیچ‌وقت از دست نمی‌رود.

متن راست‌به‌چپ درست به نظر نمی‌رسد#

در فارسی و عربی، aipager در متن خودش علامت‌های جهت نامرئی می‌گذارد تا هر خط راست به چپ خوانده شود، و اسم سشن‌ها، فرمان‌ها و کد را چپ به راست نگه می‌دارد. اگر خطی باز هم به هم ریخته به نظر می‌رسد، بیشتر وقت‌ها برنامهٔ تلگرامی است که متن با جهت‌های مختلف را جور دیگری می‌کشد: قبل از گزارش، آن را در برنامهٔ دیگری چک کنید (گوشی در برابر Desktop یا Web). جواب‌های خود Claude همان‌طور که Claude نوشته نشان داده می‌شوند، بدون اینکه علامتی اضافه شود.

یک کلمهٔ ترجمه‌شدهٔ کیبورد در چت دیگری کاری نمی‌کند#

کیبورد هر چت به زبان همان چت است. کلمه‌های کیبورد اصلی (وضعیت، توقف، جدید، بستن و بقیه) در هر چت و به هر زبانی فهمیده می‌شوند، و کلمه‌های انگلیسی همیشه کار می‌کنند. کلمهٔ دکمه‌های قالب و فرمان فرق دارد: اگر در چتی که زبان دیگری دارد تایپ شود، یک پیام برای Claude است، نه یک دکمه، پس «Clear» روسی هیچ‌وقت در یک چت فارسی یا انگلیسی ‎/clear را اجرا نمی‌کند. از خود دکمه استفاده کنید، یا فرمان انگلیسی (‎/clear). اگر بعد از عوض شدن زبان چت، کیبوردی قدیمی به نظر می‌رسد، ‎/start را بفرستید تا کیبورد فعلی را بگیرید. کلمه‌ای که اسم یکی از سشن‌هایتان هم هست با همان سشن حرف می‌زند. ‎/mode همیشه ask،‏ auto و full را مود می‌خواند، و یک کلمهٔ ترجمه‌شدهٔ مود را فقط وقتی سشن حساب می‌کند که یک سشن روشن دقیقاً همین اسم را داشته باشد.

هنوز گیر کرده‌اید؟#

یک گزارش مشکل بفرستید: در چت خصوصی‌تان با ربات زیر ‎/help روی گزارش مشکل بزنید، یا در ترمینال aipager report را اجرا کنید. قبل از اینکه چیزی فرستاده شود کل گزارش را می‌بینید، و هیچ چت، پیام، اسم، مسیر یا توکنی در آن نیست (گزارش مشکل را ببینید). بعد از ارسال، یک کد پیگیری مثل ap1-7c41d09e2b3a می‌گیرید.

بعد، اگر می‌خواهید درباره‌اش حرف بزنید، در github.com/dev-aly3n/aipager/issues یک issue باز کنید و همان کد را بنویسید. لطفاً خروجی aipager doctor یا aipager logs را در issue نگذارید: آیدی چت، مسیرهای پوشهٔ خانه، اسم سشن‌ها و اول پیام‌هایتان در آن‌هاست. اگر یک خط لاگ لازم باشد، سازندهٔ aipager همان یک خط را می‌خواهد، و شما می‌توانید قبلش هر چیز خصوصی را از آن پاک کنید.

این‌ها را هم ببینید#

  • معماری: هر جزء چه کار می‌کند.
  • مدل امنیتی: aipager به چه چیزهایی دست می‌زند و به چه چیزهایی نه.