Geleceğin terminali
(jyn.dev)- Mevcut terminal yapısının karmaşıklığına ve sınırlarına işaret ederek, girdi, çıktı ve süreç kontrolünü yeniden birleştiren yeni nesil bir terminal kavramı sunuyor
- Jupyter Notebook model alınarak, görüntü işleme, komutları yeniden çalıştırma, düzenlenebilir çıktı ve yerleşik editör gibi etkileşimli arayüzlerin nasıl mümkün olabileceği inceleniyor
- Warp ve iTerm2 örnekleri üzerinden, kabuk ile terminal arasındaki derin entegrasyon (shell integration), uzun süre çalışan süreç yönetimi, oturum ayırma ve kurtarma işlevleri somut biçimde açıklanıyor
- Veri akışı takibi (dataflow tracking) ve kalıcılık (persistence) temelinde, komutlar için undo/redo, otomatik yeniden çalıştırma ve işbirlikçi terminal gibi genişletilmiş özellikler tasarlanıyor
- Aşamalı bir yaklaşımla işlemsel CLI → kalıcı oturumlar → yapılandırılmış RPC → Jupyter benzeri frontend yönünde ilerleyen kademeli bir inşa stratejisi öneriliyor
Terminalin temel yapısı
- Terminal dört bileşenden oluşur: terminal emülatörü, sanal terminal (PTY), kabuk, süreç grubu
- Terminal emülatörü, ekranda ızgara yapısını render eden programdır
- PTY, çekirdek içindeki durumdur; girdiyi süreç grubuna iletir ve sinyal dönüşümünü üstlenir
- Kabuk, girdiyi okuyup ayrıştıran ve süreç oluşturan bir olay döngüsü görevi görür
- Süreçler, girdi ve çıktı üzerinden bu bileşenlerle etkileşime girer
- Girdi yalnızca basit metin değildir; sinyaller de içerir. Çıktı ise biçimlendirmeyi ifade eden ANSI kaçış dizilerinden oluşur
Daha iyi bir terminal tasarımı
- Mevcut terminaller işlevsel açıdan çok sayıda kısıta sahip olduğu için genişletilebilirlik ve etkileşimlilik bakımından yetersiz kalır
- Jupyter Notebook, geleneksel bir VT100 emülatöründe mümkün olmayan işlevler sunar
- Yüksek çözünürlüklü görüntü render etme
- Geçmiş çıktıyı eklemek yerine değiştiren bir "baştan yeniden çalıştır" düğmesi
- Kaynak kodun ve çıktının yerinde yeniden yazılabildiği "görünümler" (ör. Markdown'ı kaynak olarak ya da render edilmiş HTML olarak göstermek)
- Sözdizimi vurgulama, sekmeler, paneller ve fare desteği içeren yerleşik bir editör
- Ancak kabuğu çekirdek olarak kullanma fikrine dayalı bir Jupyter notebook çeşitli sorunlarla karşılaşır
- Kabuk komutları tek seferde aldığı için sekme tamamlama, sözdizimi vurgulama ve otomatik öneriler çalışmaz
- Uzun süren süreçleri ele alma sorunu: Jupyter varsayılan olarak hücre tamamlanana kadar çalıştırır; iptal edilebilir ama duraklatma, sürdürme, etkileşim kurma ve çalışan süreçleri görüntüleme mümkün değildir
- "Hücreyi yeniden çalıştır" düğmesi bilgisayarın durumunda sorunlara yol açabilir (özellikle
rm -rfgibi komutlar içeriyorsa) - Geri alma / yeniden yapma çalışmaz
Bu nasıl çalışabilir?
-
Kabuk entegrasyonu (Shell Integration)
- Warp terminali, terminal ile kabuk arasında yerel entegrasyon kurar
- Terminal, her komutun başlangıcını ve bitişini, çıktısını ve kullanıcı girdisini anlayabilir
- Standart özellikler (özel DCS) kullanılarak uygulanır
- iTerm2 de benzer biçimde OSC 133 kaçış kodlarını kullanabilir
- Tek bir kısayolla komutlar arasında gezinme
- Komut tamamlandığında bildirim
- Çıktı ekranın dışına taştığında mevcut komutu "overlay" olarak gösterme
- Warp terminali, terminal ile kabuk arasında yerel entegrasyon kurar
-
Uzun süre çalışan süreç yönetimi
- Etkileşim kurma (interacting):
- Uzun süren bir süreçle etkileşim kurmak için çift yönlü iletişim gerekir
- TUI örnekleri:
top,gdb,vim - Jupyter, değiştirilebilir ve güncellenebilir etkileşimli çıktı tasarımında güçlüdür
- TUI örnekleri:
- Beklenen terminal özelliği: her zaman bir "serbest giriş hücresi" sunmak
- Etkileşimli süreç pencerenin üst kısmında çalışırken alt kısımda giriş hücresi bulunur
- Uzun süren bir süreçle etkileşim kurmak için çift yönlü iletişim gerekir
- Askıya alma (suspending):
- Bir süreci "duraklatmak", "iş denetimi (job control)" olarak adlandırılır
- Modern terminallerin, askıya alınmış ve arka plandaki süreçleri kalıcı görsel göstergelerle sunması beklenir
- IntelliJ'nin alt görev çubuğunda "Dizin oluşturuluyor..." göstermesine benzer
- Bağlantıyı ayırma (disconnecting): oturum ayırma ve kurtarma için üç yaklaşım vardır
- Tmux / Zellij / Screen: terminal emülatörü ile program arasına ek bir terminal emülatörü yerleştirir. Sunucu PTY'ye sahip olur ve çıktıyı render eder; istemci ise çıktıyı gerçek terminal emülatöründe gösterir. İstemci ayrılabilir, yeniden bağlanabilir ve birden fazla istemci aynı anda bağlanabilir. iTerm, tmux istemcisini atlayıp doğrudan sunucuyla iletişim kuran kendi istemcisi gibi çalışır
- Mosh: SSH yerine geçen bir araçtır. Ağ kesintisinden sonra terminal oturumuna yeniden bağlanmayı destekler. Sunucuda bir durum makinesi çalıştırır ve görünüm alanındaki artımlı farkları istemciye oynatır. Multiplexing ve scrollback'in terminal emülatörü tarafından ele alınması beklenir. İstemci ağ tarafında fiilen çalıştığı için yerel satır düzenleme anlıktır
- alden/shpool/dtach/abduco/diss: yalnızca istemci/sunucu modeliyle oturum ayırma ve sürdürmeyi ele alır; ağ desteği ya da scrollback içermez, kendi terminal emülatörünü de barındırmaz. tmux ve mosh'a kıyasla daha yüksek düzeyde ayrışma sağlar
- Etkileşim kurma (interacting):
-
Yeniden çalıştırma ve geri alma
- Çözüm, veri akışı takibidir
- Bu yaklaşım bugün pluto.jl tarafından Julia derleyicisine bağlanarak uygulanıyor
- Önceki hücrelere bağımlı hücreleri gerçek zamanlı günceller
- Bağımlılıklar değişmediyse hücreleri güncellemez
- Gerektiğinde kodu yeniden çalıştıran, elektronik tablo benzeri bir Jupyter deneyimi sunar
- Bunun ortogonal kalıcılık (orthogonal persistence) ile genellenmesi
- Süreçleri sandbox içine alır, tüm I/O'yu izler ve sandbox içindeki başka süreçlerle iletişim kurmadıkları sürece "fazla tuhaf" şeyleri engeller
- Süreçler, girdinin saf fonksiyonları olarak ele alınabilir; girdi ise "tüm dosya sistemi, tüm ortam değişkenleri, tüm süreç özellikleri"dir
Türetilen işlevler
- Jupyter frontend gerekli:
- Runbook'lar (aslında yalnızca Jupyter ve PTY primitifleriyle inşa edilebilir)
- Garip özel diller veya ANSI renk kodları olmadan, sade CSS kullanan terminal özelleştirmesi
- Çıktı/zaman damgasına göre komut arama: mevcut oturumun tüm çıktısında ya da tüm komut girdi geçmişinde arama yapılabilir, ancak akıllı filtreler yoktur ve çıktı oturumlar arasında kalıcı değildir
- Kabuk entegrasyonu gerekli:
- Her komut için zaman damgası ve çalışma süresi
- Ağ sınırlarının ötesinde bile yerel satır düzenleme
- Sekmeye basmadan kabuk komutları için IntelliSense ve terminale entegre render etme
- Sandbox takibi gerekli:
- Sandbox takibinin tüm işlevleri: işbirlikçi terminal, komutlarla değiştirilen dosyuları sorgulama, çalışma anında düzenlenebilir asciinema, build sistemi takibi
- Akıllı aramayı, komutun çalıştırıldığı andaki disk durumunda da arama yapacak şekilde genişletme
- Geri alma / yeniden yapmayı git'e benzer bir dallanma modeline genişletme (emacs undo-tree bunu zaten destekler), süreç ağacının birden fazla "görünümünü" sunma
- Undo-tree modeli ve sandboxing sayesinde LLM'lere proje erişimi verip birden fazlasını aynı anda paralel çalıştırmak mümkün olur; birbirlerinin durumunu ezmezler ve yapılan işleri inceleyip düzenleyebilir, daha sonra kullanılacak runbook'lar olarak kaydedebilirler
- Üretim ortamında makinenin durumunu etkilemeden yalnızca mevcut durumu inceleyen terminaller
Adım adım inşa stratejisi
-
1. aşama: İşlemsel semantik (transactional semantics)
- Terminali yeniden tasarlarken terminal emülatöründen başlamak yanlış bir yaklaşımdır
- Kullanıcılar emülatörlerine bağlanır; yapılandırma, görünüm ve tuş atamalarını özelleştirir
- Emülatör değiştirme maliyeti yüksektir
- Doğru yöntem, CLI katmanından başlamaktır
- CLI programlarını kurmak ve çalıştırmak kolaydır, geçiş maliyeti çok düşüktür
- Tüm iş akışını değiştirmeden tek seferlik kullanılabilir
- Terminal için işlemsel anlam taşıyan bir CLI yazmak
transaction [start|rollback|commit]gibi bir arayüzstartsonrasında yapılan her şey geri alınabilir- Yalnızca bununla bile tüm işi kurmak mümkün olabilir
- Terminali yeniden tasarlarken terminal emülatöründen başlamak yanlış bir yaklaşımdır
-
2. aşama: Kalıcı oturumlar (Persistent Sessions)
- İşlemsel semantik sağlandıktan sonra kalıcılığı tmux ve mosh'tan ayırmak
- PTY kalıcılığı elde etmek için istemci/sunucu modeli gerekir
- Çekirdek, PTY'nin iki tarafının da her zaman bağlı olacağını varsayar
- alden benzeri komutlar ya da benzer kütüphaneler kullanılarak, terminal emülatörü veya PTY oturumu içinde çalışan programları etkilemeden basitçe uygulanabilir
- Scrollback sağlamak için sunucu giriş/çıkışı süresiz olarak depolar ve istemci yeniden bağlandığında tekrar oynatır
- Terminal emülatörü bunu diğer çıktılar gibi ele alınan yerel scrollback olarak sunar
- Rastgele bir başlangıç noktasından oynatma ve sürdürme mümkündür
- ANSI kaçış kodlarını ayrıştırmak gerekir ama yeterli çabayla yapılabilir
- Mosh benzeri ağ üzerinden sürdürme için Eternal TCP kullanmak (verimlilik için QUIC üzerinde inşa edilebilir)
- PTY kalıcılığı ile ağ bağlantısı kalıcılığını ayırır
- Eternal TCP saf bir optimizasyondur:
ssh host eternal-pty attachkomutunu döngüde çalıştıran bir bash betiği üzerine kurulabilir
- Bu noktada, tmux'taki gibi tek bir terminal oturumuna birden fazla istemci bağlanabilir; pencere yönetimini ise hâlâ terminal emülatörü üstlenir
- Tümleşik pencere yönetimi istenirse, terminal emülatörü iTerm gibi tmux -CC protokolünü kullanabilir
- Bu aşamadaki her parça işlemsel semantikten bağımsız biçimde paralel yürütülebilir, ancak tek başına iş kurmak için yeterli değildir
-
3. aşama: Yapılandırılmış RPC
- İstemci/sunucu modeline dayanır
- Sunucu terminal emülatörü ile istemci arasına girdiğinde, I/O'yu metadata ile etiketleme gibi işlevler uygulanabilir
- Tüm verilere zaman damgası eklenebilir
- Girdi ile çıktı ayırt edilebilir
- xterm.js benzer şekilde çalışır
- Kabuk entegrasyonuyla birleştirildiğinde, veri katmanında kabuk istemi ile program çıktısı ayrıştırılabilir
- Terminal oturumunun yapılandırılmış günlüğü elde edilir
- Günlük asciinema gibi kayıt olarak tekrar oynatılabilir
- Tüm komutları yeniden çalıştırmadan kabuk istemi dönüştürülebilir
- Jupyter Notebook veya Atuin Desktop'a içe aktarılabilir
- Komutlar kaydedilip daha sonra betik olarak yeniden çalıştırılabilir
- Terminal veriye dönüşür
-
4. aşama: Jupyter benzeri frontend
- Terminal emülatörüne ilk kez dokunulan aşamadır ve bilinçli olarak en sona bırakılmıştır
- Çünkü geçiş maliyeti en yüksektir
- İnşa edilen tüm işlevlerden yararlanarak iyi bir arayüz sunar
transactionCLI'si, iç içe işlemler istenmediği sürece artık gerekli değildir- Tüm terminal oturumu varsayılan olarak bir işlemle başlar
- Tüm parçalar birleştirildiği için yukarıda sözü edilen tüm türetilmiş işlevler sağlanır
- Terminal emülatörüne ilk kez dokunulan aşamadır ve bilinçli olarak en sona bırakılmıştır
Sonuç
- Bu yapı iddialı ve son derece hırslı; tamamının inşasının yaklaşık 10 yıla kadar sürebileceği öngörülüyor
- Sabırla, adım adım ilerlemek gerekiyor
- Bu yazının birine ilham verip bunu bizzat inşa etmeye başlamasını umuyor
1 yorum
Hacker News görüşleri
Yazının tamamını okuyunca, ilk başta sadece bir NIH tarzı istek listesi gibi göründü
Terminalin yerini alabilecek pek çok alternatif zaten varken, yazıda bunlardan hiç bahsedilmemişti
Örneğin Emacs, Lisp tabanlı bir VM; işlevleri yeniden tanımlamak kolay ve komutlar açıklamalı işlevler. Çıktı buffer’lar üzerinden yönetiliyor, birden çok pencere ve frame döşemeli şekilde yerleştirilebiliyor. CLI aynen kullanılabiliyor (
vterm,eatvb.) ya da REPL akışına geçilebiliyor (shell-mode,eshellvb.). Grafik de destekliyor ama tam bir 2D bağlamı değilBir başka örnek olarak Acme, Emacs’e benziyor ama tüm metnin komut olabildiği bir etkileşimli metin ortamı. Smalltalk da benzer bir felsefeye sahip ama daha çok IDE’ye yakın
Ben Emacs içinde GPTel kullanarak eski bir Latince ders kitabı PDF’sini otomatik olarak parçaladım ve OCR ile org-mode biçimine dönüştürdüm. Sonuçta, bir kelimeyi seçince anında sözlükte aratabiliyorum, bir cümleyi seçince de LLM dilbilgisi çözümlemesi yapıyor. 1970’lerden kalma bir metin editörü böylece gelecekçi bir öğrenme platformuna dönüşmüş oluyor
Emacs, Jupyter, VSCode gibi platformlar güçlü ama tamamlanmış bir uygulamadan çok özelleştirme temelli platformlar.
Gerçek yenilik olacaksa, karmaşık yapılandırmalar yerine Docker container’ı ya da çalıştırılabilir dosya olarak kolayca yeniden üretilebilir biçimde dağıtılmalı
Terminalin halefinin ille de metin tabanlı olması gerekip gerekmediğinden emin değilim
Geleceğin terminali bir API biçiminde olabilir ya da OAuth kimlik doğrulamasıyla uzaktan çağrılabilir. Girdi ve çıktı artık CLI metni olmak zorunda olmayabilir.
Bunun yerine nesne tabanlı girdi/çıktıya geçip, komutları ve veri yapılarını API üzerinden keşfedilebilir hale getirebiliriz.
Terminal 70’lerin bir mirası ve bugün çok daha iyi alternatifler gayet mümkün
JSON çıktısı eklenirse
jqgibi araçlarla pipeline kurulabilir.“worse is better” denilen, sadeliğin avantaj olduğu felsefe sayesinde onlarca yıldır evrim geçirdi
PowerShell’de olduğu gibi kendi kendini tanımlayan nesneler aktarılırsa çok daha güçlü bir bileşim mümkün olur
Bununla ilgili örnekleri blog yazımda derledim
Komut temelli sezgisel akış kayboluyor ve API yapısını ezberlemek gerekiyor.
Yapay zeka tabanlı otomatik tamamlama ve nesne yapısı keşfi olsaydı, bu zayıflık telafi edilebilirdi
https://www.nushell.sh/
Ama metin tabanlı, evrimleşmiş bir terminal için hâlâ hayal edilebilir, somut bir öneri olması ilgimi çekiyor
Terminalin bugüne kadar hayatta kalmasının nedeni uyumluluk ve otomasyon imkânı
GUI’ye göre script’lenmesi daha kolay ve her şey yeniden üretilebilir ve aranabilir
Eskiden Neovim’in alt-screen geçişi beni rahatsız ederdi ama böyle küçük UX ayrıntıları da önemli
Bilgisayarla ilk tanıştığımda da, terminali öğrendiğimde de iki kez âşık oldum
İlgili projeler arasında şunlar var
18 ay önce Windows Terminal içinde benzer bir deneme yapmıştım
GitHub yorumunda kayıtlı
Ama Polyglot Notebooks kullandıktan sonra, onun çok daha doğal olduğuna karar verip oraya geçtim
Emredici backend’i bir Jupyter kernel’iyle değiştirip, bunu notebook tarzı etkileşimli belge olarak kullanmak çok daha verimli
Eskiden TopShell adlı bir projeyle işlevsel programlama temelli bir shell+terminal yapmıştım
https://github.com/topshell-language/topshell#readme
Potansiyeli var ama tam teşekküllü bir alternatif olması için daha çok iş gerekiyor
Görsel ya da video gösterebilen bir terminal arıyordum
Sadece tarayıcı gibi davranan bir terminal olsa güzel olurdu.
Mesela
browser google.com/mapsgibi bir komutla doğrudan etkileşimli olarak açılabilsefbi,omxplayervb.) işiÖneri, pseudo-terminal (PTY) yapısını genişletip JSON-RPC tabanlı, bant dışı bir kanal eklemek
Mevcut escape sequence’lerin çok sınırı var.
Bu yöntemle kademeli ve geriye dönük uyumlu bir geçiş mümkün olur.
LSP ya da MCP gibi özellik pazarlığı yapılabilir ve kernel sadece kanalı sağlamakla yetinir
Böylece pipeline ve redirection aynen çalışır, renkli çıktı da korunur