Skip to content

Latest commit

 

History

History
365 lines (259 loc) · 20.6 KB

File metadata and controls

365 lines (259 loc) · 20.6 KB

claude-code-session-handoff

English · 简体中文 · 日本語 · 한국어 · Español · Français

کلود کد نشست‌های طولانی را به‌طور خودکار فشرده می‌کند: بخش عمدهٔ گفت‌وگوی شما را حذف می‌کند، جایش یک خلاصه می‌گذارد و ادامه می‌دهد. معمولاً از آنجا می‌فهمید که مدل دوباره چیزهایی را می‌پرسد که دو ساعت پیش تعیین شده بود.

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

یک دام پیکربندی را هم تشخیص می‌دهد که دانستنش ارزش دارد، حتی اگر هیچ‌کدام از اینها را نصب نکنید — گیره را ببینید.


نصب

به پایتون ۳.۸ یا بالاتر و کلود کد نیاز دارد. چیز دیگری لازم نیست؛ هیچ وابستگی‌ای برای نصب وجود ندارد.

git clone https://github.com/IRDcode/claude-code-session-handoff
cd claude-code-session-handoff
python install.py --dry-run     # اول همهٔ تغییرها را ببینید
python install.py

سپس کلود کد را دوباره اجرا کنید و ببینید چه چیزی اندازه‌گیری شده است:

python ~/.claude/skills/long-session-handoff/scripts/session_weight.py --explain

نصب پیش‌فرض شیوهٔ مدیریت زمینه در کلود کد را تغییر نمی‌دهد. فشرده‌سازی خودکار دست‌نخورده می‌ماند؛ این نگهبان فقط پیش از آنکه فشرده‌سازی فرصت اجرا پیدا کند، تحویل را انجام می‌دهد. برای حذف کامل:

python install.py --uninstall

از settings.json پیش از دست‌زدن نسخهٔ پشتیبان گرفته می‌شود، هوک‌ها و نوار وضعیت موجودتان دست‌نخورده می‌مانند، و نصب دوباره هیچ اثری ندارد.

چه چیزی نصب می‌شود

مسیر چیست
~/.claude/skills/long-session-handoff/ روالی که مدل دنبال می‌کند، به‌همراه سه اسکریپت
~/.claude/hooks/session-weight-watch.py آشکارساز، روی چهار رویداد
~/.claude/hooks/statusline-weight.py نمایش میزان پرشدگی در نوار وضعیت، در هر رندر
~/.claude/runtime/ وضعیت ضدِ سرسام، یک گزارش، و حافظهٔ نهان اندازه‌گیری
~/.claude/handoffs/ خروجی‌ها، و chains.json که والد و فرزند را به هم وصل می‌کند

چهار رویداد هوک ثبت می‌شود — UserPromptSubmit، SessionStart، PreCompact و PostCompact. هوک‌های موجود شما روی این رویدادها حفظ می‌شوند.

تفاوت با رفتار پیش‌فرض

کلود کد پیش‌فرض با نصب این ابزار
وقتی نشست پر می‌شود فشرده‌سازی اجرا می‌شود؛ بخش عمدهٔ گفت‌وگو دور ریخته و با خلاصه جایگزین می‌شود خیلی پیش از آن، تحویل به شما پیشنهاد می‌شود
نشست بعدی چه می‌داند هر آنچه خلاصه گرفته باشد — و نویسندهٔ خلاصه همان عاملی است که پیشاپیش رشتهٔ کار را از دست داده بود رونوشت خودِ والد، خواندهٔ کامل و بازبینی‌شده با شمارش
تاریخِ دورریخته در نشست جاری بی‌ارجاع است از دیسک در 05-dropped-context.md بازیابی می‌شود
واقعاً چقدر پر است؟ /context درصد پنجره را نشان می‌دهد نوار وضعیت درصدِ دیواری را نشان می‌دهد که واقعاً نشست را تمام می‌کند
بعداً پیدا کردن ادامه پیمایش /resume chains.json والد، فرزند، میزان پرشدگی در لحظهٔ انتقال، و بازبینی‌شدن خواندن را ثبت می‌کند

نوار وضعیت این‌گونه است:

Opus 5 | ████████░░ 85% 830k/977k | 696t 402tc 6.1h | HANDOFF DUE (5) | no-compact

درصدِ دیوار، نه درصدِ پنجره. این دو با هم تفاوت دارند، گاه به اندازهٔ پنج برابر، و همین موضوعِ بخش بعدی است.

گیره

خواندنش ارزش دارد، حتی اگر چیزی نصب نکنید.

کلود کد دو نقطهٔ متفاوت دارد که نشست در آن پایان می‌یابد:

compaction fires at    window  − reply reserve (~20k) − summary buffer (~13k)
sending is refused at  ceiling − reply reserve (~20k) − margin (~3k)

اولی وقتی فشرده‌سازی روشن است اعمال می‌شود و دومی وقتی خاموش است. پس پنجرهٔ ۲۰۰٬۰۰۰ توکنی حدود ۱۶۷٬۰۰۰ فشرده می‌شود.

دام اینجاست: autoCompactWindow در settings.json بی‌صدا تا سقف مدل پایین آورده می‌شود. اگر در برابر سقف ۲۰۰٬۰۰۰ عدد ۱٬۰۰۰٬۰۰۰ بخواهید، همان ۲۰۰٬۰۰۰ را می‌گیرید — و هیچ جای رابط کاربری این را نمی‌گوید. نشستی که برای یک میلیون توکن تنظیم شده، سه بار پشت‌سرهم در ۱۶۷٬۰۰۰ فشرده می‌شود، در حالی که حدود ۸۳۰٬۰۰۰ توکنِ پول‌داده‌شده بی‌استفاده می‌ماند.

این فرضی نیست. خودِ نقطهٔ آغاز این مخزن است: سه فشرده‌سازی با preTokens برابر ۱۶۷٬۳۹۸ / ۱۶۷٬۰۷۱ / ۱۶۶٬۹۰۴، در برابر فایل تنظیماتی که نوشته بود autoCompactWindow: 1000000.

دستور --explain می‌گوید شما در کدام حالت هستید:

WINDOW
  client reported  1,000,000
  ceiling          1,000,000   (source DISABLE_COMPACT+CLAUDE_CODE_MAX_CONTEXT_TOKENS)
  resolved         1,000,000   (source settings)

WALL -- the token count past which no more work happens here
  1,000,000 ceiling - 20,000 reply reserve - 3,000 margin
  = 977,000   then SENDING IS REFUSED (no summary; a handoff is the only exit)

اگر settings CLAMPED to … نوشت، تنظیم پنجرهٔ شما پایین کشیده می‌شود.

تنها یک پیکربندی از گیره می‌گریزد: DISABLE_COMPACT=1 همراه با CLAUDE_CODE_MAX_CONTEXT_TOKENS. نصب‌کننده می‌تواند این را برایتان تنظیم کند، اما اول می‌پرسد و هزینه‌اش را می‌گوید، چون /compact دستی را هم از کار می‌اندازد:

python install.py --disable-compact --window 1000000

با این تنظیم، نشست دیگر با خلاصه تمام نمی‌شود — با ردِ ارسال تمام می‌شود. این یک معاملهٔ واقعی است. ردِ ارسال قابل تحمل است: تحویل می‌دهید و ادامه می‌دهید. تاریخی که بی‌صدا نابود شده باشد قابل تحمل نیست. اما اگر همهٔ هشدارها را تا خودِ دیوار نادیده بگیرید، آن نشست دیگر نوبت تازه نمی‌پذیرد، و بهتر است این را از پیش بدانید. نگهبان در ۸۵٪ فعال می‌شود و حدود ۱۴۷٬۰۰۰ توکن فضا باقی می‌گذارد، پس در عمل کار به آنجا نمی‌کشد.

اگر ترجیح می‌دهید /compact را نگه دارید، از این پرچم بگذرید. تحویل همچنان کار می‌کند.

سازگاری

هیچ‌چیز در اینجا کلود کد را وصله یا بسته‌بندی نمی‌کند. این ابزار دو رابط مستند را می‌خواند — قرارداد stdin/stdout هوک‌ها و بارِ نوار وضعیت — و رونوشت‌های JSONL را که کلاینت پیش‌تر می‌نویسد تجزیه می‌کند. همین است که باعث می‌شود از به‌روزرسانی‌هایی جان سالم ببرد که ابزارِ ساخته‌شده بر اجزای درونی را از کار می‌انداختند.

هرجا عدد دقیق لازم است، از شاهد گرفته می‌شود نه از ادعا. سه لایه:

۱. پنجره از context_window_size می‌آید — مقداری که کلاینت در هر رندرِ نوار وضعیت دربارهٔ خودش اعلام می‌کند.

۲. اگر آن نشست هرگز فشرده شده باشد، نقطهٔ فعال‌شدن از preTokens ثبت‌شده در رونوشت در همان لحظه گرفته می‌شود: نقطهٔ فعال‌شدنِ مشاهده‌شده، نه محاسبه‌شده. تابع score() آن را مقدم می‌دارد و در آن حالت corrected from observed preTokens را نشان می‌دهد.

۳. تنها در نبود هر دو، به حسابِ ذخیره‌ها بازمی‌گردد، و --explain همهٔ ورودی‌ها را نشان می‌دهد تا انحراف دیده شود، نه آنکه خاموش بماند.

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

سیستم‌عامل‌ها. پایتونِ خالص، بدون وابستگی، بدون بخش کامپایل‌شده. مسیرها همه از os.path می‌گذرند، CLAUDE_CONFIG_DIR همه‌جا محترم است، و نصب‌کننده نامِ مفسری را برمی‌گزیند که در پوستهٔ شما واقعاً کار می‌کند، نه نامی از پیش دوخته. تنها کدِ وابسته به سکو، اجبارِ UTF-8 روی stdout است که ویندوز به آن نیاز دارد و جای دیگر بی‌زیان است.

روی دستگاه خودتان راستی‌آزمایی کنید:

python tests/test_session_weight.py    # حساب، دروازه، دو دام
python tests/test_compat.py            # کف نگارشی، نقاط ورود، خروجی هوک

فایل test_compat.py همهٔ پایتون‌های دیگرِ نصب‌شده روی دستگاه شما را پیدا می‌کند و مجموعهٔ آزمون را زیر هر یک دوباره اجرا می‌کند؛ پس تفاوت نسخه به‌جای غافلگیریِ بعدی، همین حالا به‌صورت یک شکست ظاهر می‌شود.

چه وقت فعال می‌شود

هفت نشانه اندازه‌گیری می‌شود. تنها زمینه در اینکه باید جابه‌جا شویم رأی دارد؛ بقیه فقط فوریت را تعیین می‌کنند.

نشانه آستانه
زمینه در برابر دیوار ≥ ۸۵٪ ← تحویل، ≥ ۹۵٪ ← بی‌پرسش اقدام کن
نوبت‌های دستیار ≥ ۹۰۰
فراخوانی ابزار ≥ ۶۰۰
زمان کار فعال ≥ ۴ ساعت
فشرده‌سازی خودکار پیش‌تر رخ داده هر تعداد

زیر ۶۲٪ دیوار، هر نشانهٔ دیگری هم فعال شود، چیزی پیشنهاد نمی‌شود. این دروازه از آن روست که بقیهٔ نشانه‌ها جانشین فشار زمینه‌اند — ساختهٔ روزگاری که زمینه را نمی‌شد مستقیم اندازه گرفت. اندازه‌گیری‌شده روی همان نشستی که این ابزار را ساخت: ۴٬۳ ساعت کار به‌علاوهٔ دو فشرده‌سازی پیشین امتیاز «همین حالا تحویل بده» گرفت، در حالی که زمینه روی ۱۴۷٬۵۲۷ از ۹۷۷٬۰۰۰ بود — ۱۵٪. جابه‌جایی در آن لحظه ۸۲۹٬۴۷۳ توکن را بی‌هیچ دستاوردی دور می‌ریخت.

دو نکتهٔ اندازه‌گیری که مهم‌تر از ظاهرشان هستند:

  • زمان فعال جمع فاصله‌های کمتر از ۱۰ دقیقه است، نه آخری منهای اولی. نشستی که یک‌شب باز مانده باشد ۴۴ ساعت بازه و ۱۱ ساعت کار نشان می‌دهد؛ امتیازدادن به بازه، تحویل را روی نشستی بی‌کار فعال می‌کند.
  • شمار فشرده‌سازی‌ها از سطرِ نوع‌دار رونوشت خوانده می‌شود، هرگز با جست‌وجوی رشتهٔ نشانه. یک بار آن نشانه را جست‌وجو کنید و همان رشته در خروجی ابزار خودتان ظاهر می‌شود و شمارش خودش را باد می‌کند.

هشدار در هر پله حداکثر یک بار می‌آید — ۲۰۰ نوبت دیگر، یا یک‌دهم دیگر از دیوار — با کف زمانی ۱۵ دقیقه. درون زیرعامل هرگز فعال نمی‌شود.

خودِ تحویل

measure  →  ask  →  export  →  create the continuation  →  it reads the parent

خروجی‌گرفتن پنج فایل می‌نویسد: هر پیام کاربر عیناً (از جمله آنهایی که میان نوبت فرستاده شده‌اند و آسان گم می‌شوند)، هر پیام مهم دستیار، رونوشت کامل با بارِ ابزارهای کوتاه‌شده، فهرستی از شمارش‌ها، و آنچه فشرده‌سازی‌های پیشین دور ریخته‌اند.

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

بعد شناسه و نام را می‌گیرید:

claude --resume 7157caa1-11ce-4f29-a46a-09913d483fb0

یا در /resume نام را جست‌وجو کنید؛ نام واژه‌های موضوع والد را به‌همراه (cont. 2) با خود دارد.

خودتان راستی‌آزمایی کنید

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

# نشست من دقیقاً کجا تمام می‌شود و چرا؟
session_weight.py --explain

# میزان پرشدگی فعلی، با نام هر نشانه
session_weight.py --session-id <uuid>

# خوانا برای ماشین
session_weight.py --session-id <uuid> --json

برای اطمینان از اثرگذاری یک تغییر پیکربندی، به فایل اعتماد نکنید — رونوشت را بخوانید. نخستین نوبتی را پیدا کنید که جمع توکن‌هایش از آستانهٔ قدیمی گذشته، و بررسی کنید که پس از آن سطر فشرده‌سازی تازه‌ای نیامده باشد.

محدودیت‌ها

بی‌پرده گفته می‌شود، چون ابزاری که اندازه می‌گیرد باید دربارهٔ آنچه اندازه نگرفته هم صادق باشد:

  • ذخیره‌ها (~۲۰k / ~۱۳k / ~۳k) از رفتار مشاهده‌شده استخراج شده‌اند. نسخه‌ای در آینده می‌تواند آنها را تغییر دهد. دفاع سه لایه است: پنجره‌ای که خودِ کلاینت اعلام می‌کند، مقدار واقعی preTokens ثبت‌شده در رونوشت (نقطهٔ فعال‌شدنِ مشاهده‌شده، که score() آن را مقدم می‌دارد)، و تنها در پایان همین حسابِ ذخیره‌ها — گمانه فقط لایهٔ سوم است.
  • دیوارِ ردِ ارسال محاسبه و تأیید متقابل شده، نه آنکه عمداً به آن رسیده باشیم. نگهبان طوری طراحی شده که هرگز به آن نرسید.
  • روی ویندوز با پایتون ۳.۱۱، ۳.۱۲ و ۳.۱۴ آزموده شده و با گرامر ۳.۸ نیز بررسی شده است. لینوکس و مک‌اواس باید کار کنند — جز کدگذاری کنسول، کدِ وابسته به سکو باقی نمانده — اما هیچ‌کدام سرتاسری اجرا نشده‌اند.
  • خروجی پنج‌فایلی و امتیازدهنده زیر پوشش مجموعهٔ آزمون هستند. بیدارکردنِ بی‌رابط به این بستگی دارد که فایل اجرایی claude شما قابل اجرا باشد؛ اگر نباشد، خروجی‌گرفتن همچنان موفق می‌شود و ابزار می‌گوید قدم بعدی چیست.
  • حافظهٔ نهان پرامپت: تحویل نشستی تازه آغاز می‌کند، پس حافظهٔ نهانش سرد شروع می‌شود. برای نشستی که به دیوار نزدیک است معاملهٔ خوبی است؛ با این حال هزینه است.

مشارکت

گزارش اشکال خوش‌آمد است، به‌ویژه «عددها در محیط من درست نبود» — خروجی --explain را ضمیمه کنید. اگر نسخه‌ای از کلود کد این حساب‌وکتاب را جابه‌جا کند، همین گزارش سریع‌ترین راه اصلاح است.

پیش از باز کردن PR، هر دو مجموعهٔ آزمون را اجرا کنید:

python tests/test_session_weight.py
python tests/test_compat.py

امنیت

فایل SECURITY.md دقیقاً می‌گوید چه چیزی خوانده می‌شود، چه چیزی نوشته می‌شود، و چه چیزی روی شبکه فرستاده می‌شود (هیچ چیز). پیش از نصب چیزی که به فایل‌های نشست شما دست می‌زند، خواندنش ارزش دارد.

پروانه و اعتبار

MIT — LICENSE را ببینید. استفاده، تغییر و بازپخش آزاد است، از جمله تجاری. تنها شرط این است که اعلان حق‌تکثیر و متن پروانه همراهش بمانند، تا انشعاب یا نسخهٔ بازبسته‌بندی‌شده هم بگوید از کجا آمده است.

اگر از این رویکرد یا این یافته‌ها استفاده کردید — به‌ویژه تشخیصِ گیره‌خوردنِ پنجره — یک لینک بازگشت مایهٔ خوشحالی است. فایل CITATION.cff هست تا دکمهٔ «Cite this repository» در گیت‌هاب چیز درستی بسازد.

نوشتهٔ IRDkiya.