KURULUM METNİNİ GÖR
Terminal sekmelerime durum ışığı ve otomatik ad kur. Tarifi harfiyen uygula. Bana soru sormadan bitir.
ORTAMI KORU
Önce iki şeyi öğren: işletim sistemini (Mac, Windows ya da Linux) ve Claude Code sürümünü (claude --version). İkisini de bana tek satırda söyle. Sürüm komutu çalışmazsa kurulumu bulamadığını yaz ve dur. Desteklenmeyen ayarı kurmuş gibi gösterme.
Bu tarif Mac'te yazıldı ama mantığı her sistemde aynıdır. Windows ya da Linux'taysam reddetme, durma: aynı sonucu o sistemin kendi araçlarıyla kur. Komutları, yolları, betik dilini, ses ve paket aracını o sisteme çevir; testleri de orada koş. Yalnız o sistemde gerçekten mümkün olmayan tek parçayı atla, sebebini tek satırla söyle, gerisini kur.
Aşağıdaki ~/.claude yolları, varsa CLAUDE_CONFIG_DIR klasörünü ifade eder. Komutlara gerçek mutlak yolu güvenli tırnaklarla yaz; boşluklu yolları dene.
Eksik klasörleri oluştur. settings.json yoksa boş JSON nesnesiyle başla. Varsa yalnız ilgili alanları birleştir; diğer ayarları koru.
Değişecek dosyaların tarihli yedeğini al; eski yedeği ezme. Aynı kurulum tekrarlandığında kancaları ve kuralları çoğaltma.
Gerçek kullanıcı ayarlarını test verisiyle değiştirme. Testleri geçici klasörde koş. Sonuç belirsizse kuruldu deme.
WINDOWS VE LINUX
Işık, ses, ad ve kilit kuralları her sistemde aynıdır; yalnız araçlar değişir. Betikleri Claude Code'un o sistemde kancaları çalıştırdığı kabuğa göre yaz: Windows'ta Git Bash varsa .sh, yoksa PowerShell .ps1. Aşağıdaki tty ve ps adımları Mac ve Linux içindir. Windows Terminal ve VS Code da aynı başlık kaçış dizisini anlar. Windows'ta /dev/tty yerine önce CONOUT$ konsoluna yazmayı, olmazsa PowerShell'de [Console]::Title ayarını dene. Sınavdan sonra gerçek bir sekmede başlık değişmediyse kuruldu deme, hangi parçanın çalışmadığını söyle.
HEDEF
Her Claude Code sekmesinin başlığı şöyle görünsün: 🟡 Reels script
🟡 Claude çalışıyor. 🔵 Cevabımı bekliyor, bir de ses çalar. ⚪ Park: zamanlanmış bir uyanışı var, şu an kimseyi beklemiyor.
Ad, sohbetteki ilk gerçek mesajımdan çıkar ve bir daha değişmez.
DOSYALAR (hepsi ~/.claude/hooks altında, hepsine chmod +x)
1. sekme-isik.sh: tek argüman alır: start, working, pretool, waiting ya da stop. stdin'den kanca JSON'unu okur.
2. sekme-adi.sh: sekme-adi.sh "Başlık" [--zorla]. Adı yazar ve kilitler.
3. ilk-mesaj.sh: ilk gerçek mesajda Claude'a ad koymasını hatırlatır.
Aynı adlı dosya varsa önce benzersiz tarihli .yedek uzantısıyla kopyala.
Durum dosyaları ~/.claude/state/sekme klasöründe, oturuma göre ayrı tutulur. Bu klasör SEKME_DIZIN ortam değişkeniyle değiştirilebilsin (test için).
Durum dosyasını yazarken önce aynı klasörde geçici bir dosyaya yaz, sonra mv ile yerine koy. Aynı oturumun iki kancası aynı anda koşabilir; yarım yazılmış dosya okunmasın.
KANCALAR (~/.claude/settings.json)
Önce yedek al. Var olan kancaları SİLME, listelere ekle. Kaydedince geçerli JSON olduğunu doğrula: jq . dosya, jq yoksa python3 -m json.tool dosya. Bozulduysa yedeği geri koy.
• SessionStart: sekme-isik.sh start
• UserPromptSubmit: iki ayrı kanca girdisi olarak ekle. Önce sekme-isik.sh working, sonra ilk-mesaj.sh. Tek komut satırında birleştirme: her kanca kendi kopyasını stdin'den okur, zincirlersen ikincisine girdi kalmaz.
• PreToolUse (matcher boş): sekme-isik.sh pretool
• Notification (matcher "permission_prompt|elicitation_dialog|agent_needs_input"): sekme-isik.sh waiting
• Stop: sekme-isik.sh stop
• StopFailure: sekme-isik.sh stop
Ayrıca settings.json'daki "env" bölümüne "CLAUDE_CODE_DISABLE_TERMINAL_TITLE": "1" ekle. Yoksa Claude Code başlığı kendisi yazar ve ışığı ezer.
IŞIK KURALLARI
• working: 🟡
• pretool: 🟡. Ama tool_name AskUserQuestion ya da ExitPlanMode ise 🔵 ve ses.
• waiting: 🔵 ve ses. Sekme o an ⚪ ise ⚪ kalsın, ses çalmasın.
• start: source alanı startup ya da clear ise 🔵, sessiz. resume ya da compact ise son ışığı geri yükle, yoksa 🔵. (Sıkıştırma da start tetikler.)
• stop: sırayla bak:
1. background_tasks içinde type alanı "shell" olmayan bir görev varsa 🟡 (arkada ajan çalışıyor). type alanı yoksa o görevi shell say.
2. Değilse session_crons boş değilse ⚪ (zamanlanmış uyanış var).
3. Değilse background_tasks içinde shell görevi varsa 🟡.
4. Değilse 🔵 ve ses.
Bu alanlar JSON'da hiç yoksa 🔵 ve ses.
• Ses kuralı tek: ses yalnız 🔵 ile çalar. 🟡 ve ⚪ daima sessizdir.
• Her ışığı oturuma göre bir dosyaya kaydet.
BAŞLIĞI YAZMAK (en çok burada bozulur)
1. Kanca betikleri stdout'a ASLA bir şey yazmasın. UserPromptSubmit ve SessionStart'ta stdout Claude'un bağlamına girer. Kaçış dizisini oraya basarsan sohbet kirlenir, başlık da değişmez. Tek istisna aşağıdaki ilk-mesaj.sh hatırlatmasıdır.
2. Başlığı terminale yaz: printf '\033]0;%s\007' "$baslik" > "$tty"
3. Kanca içinde /dev/tty çoğu zaman açılmaz. Önce /dev/tty'yi dene. Olmazsa süreç ağacında yukarı çık: ps -o tty= -p PID ve ps -o ppid= -p PID ile en fazla 8 adım. Boş OLMAYAN VE "??" OLMAYAN ilk tty'yi al, başına /dev/ ekle. Bulduğun tty'yi oturuma göre bir dosyaya kaydet, sonraki çağrılarda önce oradan oku. Yazılabilir değilse sessizce çık.
4. tty bulunamazsa hiçbir şey yapma, ses de çalma, 0 ile çık.
5. Süreç ağacında 2 ya da daha fazla claude süreci varsa (iç içe çalışan Claude) hiçbir şey yapma. Yoksa içteki, dıştaki sekmenin adını ezer.
6. Ses: Mac'te afplay /System/Library/Sounds/Submarine.aiff, Linux'ta paplay varsa onu kullan. Windows'ta C:/Windows/Media klasöründeki bir .wav dosyasını PowerShell'in System.Media.SoundPlayer aracıyla çal. Arka plana at (&), bitmesini bekleme. Ses yalnız tty bulunduysa çalsın.
7. Adın içindeki kontrol karakterlerini ve emojileri temizle. 40 karakterden uzunsa kes, sonuna … koy.
8. Ad yoksa çalışma klasörünün adını kullan.
9. Her betik 1 saniyenin altında bitsin, her hata yolunda 0 ile çıksın. jq yoksa python3 ile oku.
OTURUM KİMLİĞİ
• Kanca JSON'unda session_id ve cwd var. Durum dosyalarını session_id ile adlandır.
• sekme-adi.sh kanca değildir, Claude onu Bash ile çağırır. Oturumu CLAUDE_CODE_SESSION_ID ortam değişkeninden alsın. O yoksa (eski sürüm) kancaların cwd için tuttuğu işarete baksın: kancalar her çağrıda cwd, session_id ve zamanı yazsın. Aynı klasörde son 2 dakikada tek oturum mesaj aldıysa onu kullansın. Birden fazlaysa adı yazmasın, stderr'e "Oturum ayırt edilemedi." yazıp 0 ile çıksın. Hiç eşleşme yoksa yine adı yazmasın, stderr'e "Oturum bulunamadı." yazıp 0 ile çıksın.
• sekme-adi.sh başlığı yenilerken kancaların kaydettiği tty'yi kullansın, çünkü Bash aracında tty yoktur.
AD KİLİDİ
• ilk-mesaj.sh: prompt alanı boşsa, / ile başlıyorsa ya da 10 karakterden kısaysa hiçbir şey yapmasın ve işaret de koymasın. İlk gerçek mesajda bir kez işaret koysun ve stdout'a şu cümleyi bassın (bu kancada stdout Claude'a gider, istenen de bu):
Bu sohbetin ilk gerçek mesajı. İşten 2-4 kelimelik sade bir başlık çıkar ve şunu çalıştır: ~/.claude/hooks/sekme-adi.sh "Başlık". İyi örnek: Reels script, Fatura otomasyonu. Kısaltma ya da yer tutucu yazma.
• Oturumun zaten adı varsa hatırlatma basmasın.
• sekme-adi.sh: ilk yazıştan sonra adı kilitlesin. Sonraki çağrılar adı değiştirmesin, stderr'e "Ad kilitli, tekrar deneme." yazsın ve 0 ile çıksın. --zorla kilidi kırar.
• "Başlık", "Sade Kısa Başlık" gibi yer tutucuları ve boş adı reddetsin.
• Ad yazılınca başlığı hemen yenilesin, mevcut ışığı koruyarak.
EDİTÖR AYARI
TERM_PROGRAM ortam değişkenine bak. "vscode" ise VS Code tabanlı bir editördesin (VS Code, Cursor, Windsurf, Antigravity). TERM_PROGRAM tek başına editörün adını söylemez. Süreç ağacından çalışmakta olan uygulamayı belirle; başka editörün ayarını değiştirme. O editörün kullanıcı ayar dosyasına şunu ekle: "terminal.integrated.tabs.title": "${sequence}". Mac'te dosya ~/Library/Application Support/<Editör adı>/User/settings.json yolundadır. Linux'ta XDG_CONFIG_HOME, yoksa ~/.config altında o editörün User/settings.json dosyasını bul. Windows'ta dosya %APPDATA%/<Editör adı>/User/settings.json yolundadır. Editörü kesin belirleyemezsen ortak kancaları hazırla, editör ayarını tamamlandı sayma. Bu dosyada yorum satırı olabilir: jq ile yeniden yazma, satırı dikkatle ekle, sonra dosyayı tekrar okuyup kontrol et. Bu ayar yoksa sekme başlığı hiç değişmez. Mac Terminal, iTerm2, Ghostty ve Windows Terminal ayar istemez.
TEST (bitti demeden koş, sonucu tablo olarak göster)
Betiklere SEKME_TEST=1 modu ekle. Bu kontrol tty ve iç içe süreç kontrolünden ÖNCE olsun. Testte terminali uygun varsay; gerçek tty arama, ses çalma veya başlık yazma. Yazılacak başlık ve ses kararını stderr'e bas.
Testleri SEKME_DIZIN ile geçici bir klasörde koş, gerçek durum klasörüne dokunma. Sahte JSON ile:
1. start, source startup: 🔵, ses yok.
2. working: 🟡.
3. pretool, tool_name AskUserQuestion: 🔵, ses var.
4. stop, boş background_tasks ve session_crons: 🔵, ses var.
5. stop, session_crons dolu: ⚪.
6. stop, type "agent" olan bir background_tasks: 🟡.
7. waiting, sekme ⚪ iken: ⚪, ses yok.
8. start, source compact: önceki ışık korunur.
9. sekme-adi.sh "Reels script": ad yazılır. İkinci çağrı "Başka ad": reddedilir. --zorla ile: değişir.
10. Önceki testlerden farklı, yeni session_id ile ilk-mesaj.sh: "/help" sessiz. "selam" sessiz. "reels için üç hook yazalım" hatırlatma basar. Aynı oturumda ikinci uzun mesaj sessiz.
Biri geçmezse düzelt ve hepsini baştan koş.
SON
Test sonuçlarından sonra son durum cümlesini yaz: "Kuruldu. Yeni bir sekme açıp ilk mesajını yaz, ad ve ışık gelecek."
Windows'taysan başlığın gerçek sekmede değiştiğini sen göremezsin; o cümleyi yazma. Şunu yaz: "Dosyalar kuruldu, testler geçti. Windows'ta başlığı ben göremiyorum: yeni bir sekme açıp ilk mesajını yaz, ad ve ışık gelmezse bana söyle, düzelteyim."