Claude'dan bir `pi` oturumu yönetmek (iki tarafta da tmux)-
Created by tests/specs/post-lifecycle.spec.ts
§ 01Claude'dan bir `pi` oturumu yönetmek (iki tarafta da tmux)
Bir işi pi kodlama ajanına (@earendil-works/pi-coding-agent, DeepSeek tabanlı) devredip Claude tarafından nasıl gözetlediğimizi anlatıyorum. Mekanizma aslında iki tmux bağlamı ve ortak bir /tmp durum klasöründen ibaret. Bu yazı işin iki taraftaki tmux borularına odaklanıyor. Üst seviye akış zaten pi-loop skill’inde duruyor (.claude/skills/pi-loop/).
Zihindeki model: iki taraf, tek ortak `/tmp`
┌─ pi tarafı (işçi) ──────────┐ ┌─ Claude tarafı (gözetmen) ──┐ │ tmux oturumu "pi-loop" │ │ Claude (Bash aracı) │ │ └ exec pi ← brief.md │ │ ├ watch.sh (arka planda) │ │ working tree'i düzenler│ │ └ opsiyonel: kendi tmux │ │ build/test çalıştırır │ │ paneli (claude-target) │ └──────────────┬──────────────┘ └──────────────┬──────────────┘ │ │ │ ortak dosya sistemi /tmp/<session>/ │ └────────────► PING ◄───────────────────┘ summary.md brief.md / ping.log / claude-target
İki taraf neredeyse hiçbir zaman birbirinin process’iyle konuşmaz. /tmp/<session>/ içindeki dosyalar üzerinden konuşurlar. O ortak klasör sözleşmenin tamamı: Bash aracının kabuğu ile kullanıcının interaktif terminali, ortamları (özellikle $TMUX) farklı olsa bile bu sayede koordine olabiliyor.
Durum klasörünün içeriği (STATE=/tmp/<session>, varsayılan oturum pi-loop):
DosyaYazanOkuyanAmaçbrief.mdlaunch.shpigörev, eklenen ping protokolü ve korkuluklarsummary.mdpiClaudeher geçişin sıralı özetiPINGpi-notifywatch.shnöbetçi dosya; ortaya çıkması uyandırma sinyalidirping.logpi-notifyinsanher ping’in salt-ekleme kaydıclaude-targetClaudepi-notifyClaude’un kendi session:window.pane’i (doğrudan)
pi tarafı: pi tmux'un _içinde_ çalışır
Bu tarafı launch.sh <brief> [session] [repo] yönetir:
tmux new-session -d -s "$SESSION" -x 220 -y 50 \ "cd '$REPO' && set -a && [ -f '$KEY_ENV' ] && . '$KEY_ENV'; set +a \ && exec pi 'Read @$STATE/brief.md and execute it. ... ping me per the protocol.'"
-dyani detached: pi’ye bağlı bir istemci yok. Claude’un Bash aracıona asla takılıp kalmaz.-x 220 -y 50cömert bir pane geometrisi sabitler ki kimse bağlıdeğilken pi’nin TUI’si tuhaf sarmasın (detached bir oturum yoksa 80×24’edüşer).- API anahtarı oturumun içinde source edilir, Claude’un kabuğunda değil.Her tmux komutu yeni, login’e yakın bir kabuk açar ve Bash aracının ortamı
DEEPSEEK_API_KEYtaşımaz.set -a; . $KEY_ENV; set +aanahtarı sadece opane içinde export eder. Varsayılan anahtar dosyası~/.myserver/deepseek.env(PI_KEY_ENVile değiştirilebilir). Bu dosyayıaslaechoetme. exec pikabuğun yerine pi’yi koyar, böylece oturum tam olarak piçıktığında ölür.watch.sh’in “ping atmadan bitti” durumunuyakalayabilmesini sağlayan şey budur.
- Brief’ini
$STATE/brief.md’ye kopyalar ve sonuna ping protokolünü ve sertkorkulukları ekler (asla commit/push/checkout/deploy yapma, asla prodSSH atma, her değişiklikten sonra doğrula). pi’nin talimatı brief dosyasıolduğu için korkuluklar görevle birlikte gider. - Aynı isimdeki eski oturumu öldürür, sonra detached bir oturum başlatır: Önemli tmux ayrıntıları:
İkinci bir eşzamanlı döngü çalıştırmak için farklı bir oturum adı geç: launch.sh /tmp/other-brief.md pi-loop-2 "$PWD".
Claude tarafı: bir dosyayı izle, saati yoklama
Claude pi’nin tmux oturumuna bağlanmaz. Bağlanmak Bash aracını bloke eder ve TTY için pi’yle kapışırdı. Bunun yerine Claude arka planda bir izleyici kurar:
bash .claude/skills/pi-loop/scripts/watch.sh pi-loop # run_in_background: truewatch.sh şunu yapar:
- Önce
rm -f $STATE/PING. Böylece bu kurulum yalnızca bir sonraki ping’detetiklenir, eski bir ping’le asla. until [ -f $STATE/PING ] || ! tmux has-session -t $SESSIONdöngüsü kurar.Yani iki koşuldan birinde uyanır: pi ping attı, ya da pi’nin oturumukayboldu (çökme veya ping atmadan bitme).- Çıkarken
summary.md’yi yazdırır (yoksa “ping atmadan bitti” der).
Claude bunu run_in_background: true ile çalıştırdığından, izleyici çıktığında harness Claude’u yeniden çağırır. Uyandırma budur. Olay tabanlıdır: yoklamak için kısa aralıklı bir ScheduleWakeup ekleme. pi sessizce biter de oturum bir şekilde takılı kalırsa diye tek bir uzun yedek uyandırma (~1800s) makul.
Claude tarafında her ping döngüsü
- İzleyicinin çıktısını (
summary.md) ve pi’nin düzenlemeleri içingit -C <repo> diff’i oku. - Eleştirel doğrula: pi API ve sembol uydurur, gerçekten var olduklarınıteyit et.
- Bağımsız olarak yeniden doğrula:
cd web && ./node_modules/.bin/vue-tsc --noEmit,CGO_ENABLED=0 go build ./..., ilgiligo test. - pi’ye bir takip mesajı enjekte et (aşağıya bak) ya da işi sarıp topla.
- Bir sonraki ping için
watch.sh’i yeniden kur.
Bir ping aradaki boşluğu nasıl geçer (`pi-notify.sh`)
pi her geçişin sonunda bash pi-notify.sh "$SESSION" "<status>" çağırır. İki teslim yöntemi var, ikisi de denenir ama dosya yöntemi her zaman çalışır:
tmux send-keys -t "$TARGET" "[pi-loop:...] <msg> — review summary.md + diff" Enter- Yöntem 1: izleme dosyası (her zaman).
ping.log’a ekler, sonratouch $STATE/PING.watch.sh’in tıkanmasını çözen tek dosya oluşturma bu. İkitaraf/tmp’yi paylaştığı için Claude nerede çalışırsa çalışsın işler. - Yöntem 2: doğrudan tmux enjeksiyonu (yalnızca Claude da tmux içindeyse).
$STATE/claude-targetClaude’un kendisession:window.pane’ini tutuyorsa,pi-notify şunu yapar: Yani pi’nin ping’ini doğrudan Claude’un girdisine bir sohbet mesajı olarakyazar. Hiçbir izleyici kurulu olmasa bile “pi sohbeti arar”. En iyi çabaprensibiyle çalışır; hedef pane yoksa pi’yi asla başarısız etmez.
Doğrudan enjeksiyonu açmak (Claude'un tmux'unun önem taşıdığı tek yer)
Doğrudan yöntem için Claude’un önce kendi tmux koordinatlarını kaydetmesi gerekir:
if [ -n "$TMUX" ]; then tmux display-message -p '#S:#I.#P' > /tmp/<session>/claude-targetelse echo "Claude tmux içinde değil, sadece izleme-dosyası yöntemi."fi
Gerçeklik kontrolü: Bash aracının alt süreci genelde boş bir $TMUX’a sahiptir, dolayısıyla bu adım atlanır ve her şeyi izleme-dosyası yöntemi taşır. Doğrudan yöntemle ancak Claude gerçekten interaktif bir tmux paneli içinde çalışıyorsa uğraş. Kullanıcı isterse, Claude isteminde ! tmux display-message -p '#S:#I.#P' çalıştırıp hedefi yapıştırmasını iste, sonra echo "<target>" > /tmp/<session>/claude-target.
Çalışan bir pi oturumuna iş enjekte etmek
Çalışma sırasında pi’ye hem Claude’un Bash aracından hem de kullanıcının kabuğundan mesaj gönderebilirsin. Aynı komut, çünkü /tmp üzerinden aynı tmux sunucusunu paylaşırlar:
tmux send-keys -t pi-loop "her düzeltmede ping atmayı bırak; son bir tarama yapıp tek ping at" Entersend-keys pi’nin girdisine sanki bir insan yazmış gibi yazar. Kapsamı yeniden odaklamak, ping’leri toplu hale getirmek (gereksiz gürültüyü azaltmak) veya pi’yi sarıp toplamak için kullan.
Canlı izleme / bağlanma (insan)
tmux attach -t pi-loop # pi'yi gerçek zamanlı izletmux ls # oturumları listeletmux kill-session -t pi-loop # pi'yi durdur (Claude istenmedikçe boşta/bağlı bırakır)
attach kullanıcının terminalinden ancak başlatıcıyla aynı tmux sunucusunu paylaşıyorsa çalışır. Onları aynı sunucuda buluşturan şey de ortak /tmp soket klasörü, ortak bir kabuk değil. Bash aracının ortamıyla interaktif kabuk başka her şeyde farklılaşabilir ama yine de aynı oturumu sürebilir.
Bu kuruluma özgü tmux tuzakları
- İki ayrı kabuk, tek tmux sunucusu. Koordinasyon ortam mirası üzerindendeğil, ortak
/tmpüzerinden olur.$TMUX,$DEEPSEEK_API_KEYya da PATHoynamalarının Claude’un kabuğundan pi paneline geçmesini bekleme. Anahtar tamda bu yüzden oturumun içinde tekrar source ediliyor. - Bayat
PING.watch.shkurulurken onu siler; nöbetçiyi elle kontroledersen, kalan birPINGyeni bir izleyiciyi anında tetikler. exec picanlılığı oturuma bağlar. pi tıkanmış bir sağlayıcı çağrısındatakılırsa pane sonsuza dek “Working…” gösterir,has-sessionhâlâ true dönerve hiç ping gelmez; izleyici sonsuza dek bekler. Uzun yedek uyandırmanınkoruduğu durum bu; pane’i tekrar kontrol et vekill-session+ yenidenbaşlatmayı düşün.- Geometri. Detached oturumlar 80×24’e düşer; pi’nin TUI çıktısının
attach/capture-paneiçinde okunabilir olması için 220×50’ye zorluyoruz. - Karışık working tree. pi’nin düzenlemeleri başka commit’lenmemiş işlerinyanına iner.
summary.mdve adı geçen dosyaların hedefligit diff’iyleayrıştır. pi asla commit atmaz; commit/deploy eden tek taraf Claude’dur(kullanıcı onayıyla).
Ayrıca bakınız
.claude/skills/pi-loop/SKILL.md: Claude’un izlediği prosedür..claude/skills/pi-loop/scripts/{launch,watch,pi-notify}.sh: kaynak.- Bellek:
feedback_tmux_means_green.md,reference_deepseek_key.md,feedback_never_kill_running_pi.md.