Situs ini dikemudikan dua tombol, seperti mesin pemiliknya. Membaca: j dan k menggulir, d dan u setengah layar, gg ke atas, G ke bawah, H dan L pindah jendela, ? membuka panduan. Spasi adalah kunci leader Neovim dan mengurus isi: Spasi lalu h beranda, r riset, p proyek, g gear, a tentang, / tag, atau Spasi lalu angka untuk melompat ke jendela bernomor itu. Home adalah prefix tmux dan mengurus jendela: Home lalu c membuka terminal, Home lalu & menutup jendela, Home lalu spasi ke jendela berikutnya. Saat fokus ada di papan ketik, h j k l memindahkan pilihan antar tombol dan Enter membukanya.

RisetR TentangA Gear: G untuk gear, papan ketik, terminal, editor, homelab.G
    ProyekP Tag: / seperti di vim: cari./
    ×
    Menu

    tmprl: Klien Temporal untuk Papan Ketik

    Klien terminal modal untuk Temporal: workflow, riwayat sebagai linimasa, payload lewat codec server, dasbor, mutasi, jadwal, dan gf dari sebuah event ke kode di baliknya. Empat crate, 1004 uji, di v0.2.1.

    Versi pertama tulisan ini dibuka dengan “TUI-nya belum ada”, karena saat itu hanya itu baris pertama yang jujur: lapisan gRPC, empat RPC, dan dokumen rancangan untuk sisanya.

    Baris itu sudah tidak berlaku. tmprl sekarang menggambar antarmuka terminal, dan modal seperti editor: tombol leader (Spasi), / untuk mencari, <C-o> untuk melompat balik, dan V untuk seleksi visual yang bisa dikenai aksi. Ini posisinya di v0.2.1, yang dirilis 2026-10-06: yang sudah bisa, dan yang belum.

    Empat crate, dibagi menurut apa yang tidak dibutuhkan untuk mengujinya

    crates/tmprl-client   semua IO jaringan: gRPC, TLS, profil, perjalanan ke codec
    crates/tmprl-core     mode, keymap, perintah, riwayat, kueri, picker
    crates/tmprl-ui       pohon jendela: split, tab, fokus (tanpa dependensi)
    crates/tmprl-tui      rendering ratatui dan masukan; biner `tmprl`

    Di tulisan pertama, diagram ini punya satu baris nyata dan tiga bertanda “rencana”. Sekarang keempatnya ada. Pembagiannya digambar supaya logika yang berat (menormalkan 60 jenis event riwayat, mengompilasi kueri visibility, pencocokan fuzzy, jumplist) jatuh ke tmprl-core, yang untuk diuji tidak butuh terminal maupun server.

    Ke sanalah ujinya pergi. Seluruh workspace punya 1004 uji: 432 di core, 444 di TUI, 81 di client, dan 47 di pohon jendela.

    Yang sudah bisa

    Workflow. Daftar yang dikendalikan kueri visibility mentah (i untuk menyuntingnya), tampilan tersimpan di <leader>1 sampai <leader>9, dan tampilan lintas beberapa namespace sekaligus.

    Riwayat. Event dikelompokkan dan bisa dilipat (za, zR, zM), F untuk mengikuti workflow yang sedang berjalan seperti tail -f mengikuti berkas, dan K untuk membuka payload event di bawah kursor. Panel itu terbelah atas-bawah secara bawaan; payload = "right" di konfigurasinya menaruhnya di sebelah daftar, yang lebih masuk akal di terminal lebar, dan di bawah 100 kolom ia menumpuk juga. Split dan tab membuat dua riwayat bisa berdampingan.

    ]f dan [f melangkah antar kegagalan, dan K di atas salah satunya menampilkan seluruh rantainya: setiap caused by sampai ke akarnya, tipenya, SDK yang melemparnya, bisa dicoba ulang atau tidak, dan stack trace-nya. Activity milik workflow yang masih berjalan menampilkan ×4/10 (∞ kalau kebijakannya tidak pernah menyerah), retry in 12s selama ia menunggu, dan kegagalan yang memicu percobaan ulang itu. Temporal tidak menulis event untuk sebuah retry, jadi datanya diambil dari describe: dibaca saat riwayat dibuka, saat R, dan tiap 5 detik di bawah F.

    Linimasa. <Space>G menggambar riwayat yang sama seperti web UI Temporal: event tiap kelompok sebagai titik di satu sumbu waktu, diwarnai menurut akhir kelompoknya. Rentang yang diam dilipat jadi ≀, dan zg membukanya.

    Tampilan linimasa sebuah riwayat yang gagal di tmprl, dengan panel payload terbuka di bawahnya

    Tangkapan layar itu, dan satu lagi di bawah, berasal dari klaster contoh di direktori demo/ repo-nya: perusahaan ekspedisi karangan di dev server lokal, dengan nama dan alamat yang dibuat-buat.

    Payload. ! menyalurkan payload lewat perintah shell, sudah terisi jq .. <leader>y menyalinnya ke papan klip sistem lewat OSC 52, jadi tetap jalan lewat SSH; di dalam tmux ia lewat tmux load-buffer -w, yang tidak butuh pengaturan tmux apa pun. Salinan yang melewati batas (65536 byte kecuali [yank] max_bytes berkata lain) ditulis ke berkas alih-alih ditolak, dan baris status menyebut tempatnya. Encoding apa pun yang tidak bisa dibaca tmprl sendiri dikirim ke codec server sebagai POST /decode, dan kalau codec-nya menolak, lencananya menyebut alasannya.

    Mutasi. Cancel, terminate, signal, delete, reset, dan update, masing-masing di bawah <leader>m. Sebelum dijalankan, konfirmasinya menampilkan perintah CLI temporal yang setara, jadi apa yang akan kamu lakukan tertulis dalam bentuk yang sudah kamu kenal:

    Terminate 3 workflows
      temporal workflow terminate --namespace prod --workflow-id order-1 --reason "…"
      type `3` to confirm   Esc to cancel

    Setiap percobaan dicatat ke ~/.local/state/tmprl/audit.jsonl beserta profil dan alamat klasternya.

    Batch atas seleksi visual. Contoh di atas adalah batch: V untuk memilih sederet baris, lalu jalankan mutasi atas semuanya, satu permintaan per baris, berurutan. Batch yang merusak meminta kamu mengetik jumlah barisnya. Delete tetap meminta kamu mengetik delete.

    Jadwal. gs berpindah ke daftar jadwal: pause, trigger, delete, backfill atas rentang seperti -7d..now, dan membuat jadwal lewat formulir multi-kolom.

    Mencari. /, n, dan N mencari dengan smartcase. Di sebuah riwayat, / juga mencocokkan nilai di dalam payload yang terbaca: /8812 menemukan nilainya di mana pun ia berada, /customer.id=8812 hanya sebagai id pelanggan. Ia tidak pernah memanggil codec, jadi saat tidak ketemu ia menyebut berapa payload terenkripsi yang tidak bisa dilihatnya. <leader>ff dan kerabatnya membuka picker fuzzy, dan masukan enam karakter atau lebih juga dikirim ke server sebagai workflow id atau run id, jadi id yang ditempel dari log menemukan workflow-nya, sudah dimuat panelnya atau belum. Bilah kueri melengkapi klausa yang sedang diketik, dan <Tab> mengambilnya. <C-o> dan <C-i> menelusuri jumplist. <C-h/j/k/l> sengaja tidak dipakai, karena itu milik tmux.

    Sebuah dasbor

    gd, atau tmprl --dashboard dari shell, membuka satu layar berisi panel atas namespace yang sedang dicakup: workflow menurut status, kegagalan dan penyelesaian sebagai grafik, tipe workflow yang paling sering gagal, task queue yang dipakai workflow berjalan, kegagalan terbaru beserta alasan masing-masing berakhir, dan workflow yang activity-nya terus dicoba ulang.

    Dasbor tmprl: hitungan status, kegagalan per menit, tipe yang gagal, task queue beserta poller-nya, kegagalan terbaru, dan workflow yang terus mencoba ulang

    Enter di atas butir mana pun membuka workflow yang diwakilinya, termasuk satu kolom grafik. h j k l bergerak sesuai arahnya, melintasi panel. Tiap task queue menampilkan backlog-nya, berapa lama tugas tertuanya menunggu, dan berapa worker yang sedang polling, dan backlog yang tidak di-poll siapa pun tampil sebagai galat.

    Angkanya dihitung di server, bukan dijumlah dari halaman pertama. Angka yang masih menunggu hitungannya digambar ~26, dan sebuah panel menulis names from 50 kalau daftar namanya berasal dari sampel, karena tipe yang terlewat halaman itu memang tetap terlewat.

    Tanpa dashboard.toml, tata letaknya mengikuti apa yang ditunjukkan namespace-nya: panel yang kosong menyerahkan tempatnya. Dengan berkas itu, tiap baris memuat panel dengan jenis, kueri, jendela waktu, dan bagian layarnya. Ia menyegarkan diri tiap 30 detik secara bawaan, dan permintaan yang gagal mempertahankan jawaban terakhir panelnya, ditandai stale.

    Dari sebuah event ke kode di baliknya

    gf di sebuah riwayat membuka $EDITOR pada kode di balik event di bawah kursor. tmprl tidak mungkin tahu bagaimana nama workflow atau activity dipetakan ke berkas di repositori orang, jadi ia bertanya ke program yang kamu sebut:

    # ~/.config/tmprl/config.toml
    [source]
    command = "~/bin/find-source"

    Program itu, sebuah resolver, menerima apa yang ada di bawah kursor sebagai JSON di stdin dan mencetak path:line. Ia boleh ditulis dengan apa saja, dan ia sendiri yang memutuskan versi kode mana yang waktu itu berjalan. Klaster contohnya membawa satu resolver sepanjang selusin baris: gf di atas book_carrier membuka editor pada func BookCarrier.

    v0.2.1 juga memperbaiki yang tersingkap karenanya. Kembali dari editor bisa mengakhiri tmprl dengan “The cursor position could not be read within a normal duration”. Sekarang ia tidak lagi menanyakan posisi kursor ke terminal saat kembali, dan ia membuang apa yang ditinggalkan editor tanpa terbaca, yang kalau tidak bisa tiba sebagai ketikan.

    Beberapa klaster, salah satunya produksi

    tmprl bisa diarahkan ke lebih dari satu lingkungan Temporal tanpa jadi berbahaya. Di konfigurasinya sendiri, tiap profil bisa membawa warna dan penanda hanya-baca:

    # ~/.config/tmprl/config.toml
    [profile.sit]
    accent = "green"
    
    [profile.prod]
    accent   = "red"
    readonly = true

    Profil hanya-baca menolak mutasi dua kali: sekali saat tombol ditekan, dan sekali lagi tepat sebelum permintaannya dikirim, jadi jalur kode yang lupa pemeriksaan pertama tetap tertahan di yang kedua. Baris status menampilkan prod [ro] sepanjang waktu, dan --readonly melakukan hal yang sama untuk satu kali jalan.

    Perubahan yang sama menangani kunci Temporal Cloud yang dibatasi ke satu namespace. Kalau daftar namespace ditolak, tmprl memakai namespace yang disebut profilnya alih-alih gagal menyala.

    Sisi shell-nya ikut digarap. -n membuka workflow sebuah namespace, -q membuka daftar dengan kueri terpasang, -w membuka riwayat dari workflow id atau run id, dan --address menimpa server milik profil sambil mempertahankan TLS dan API key-nya.

    Tetap tidak punya konfigurasi sambungan sendiri

    Bagian ini tidak berubah, dan masih keputusan rancangan yang paling dulu akan saya bela. Sambungannya dibaca dari temporal.toml yang sama dengan yang dibaca CLI temporal, dengan variabel lingkungan TEMPORAL_* yang sama dan urutan yang sama. Berkas milik tmprl sendiri cuma menambahkan apa yang tidak dikenal CLI-nya: warna, penanda hanya-baca, alamat codec, tata letak, dasbor, dan tema. Kalau CLI-nya bisa menjangkau klastermu, ini juga bisa.

    Satu detail berubah. Di macOS, CLI menyimpan berkas itu di ~/Library/Application Support, bukan ~/.config, dan tmprl sekarang melihat lokasi platform itu lebih dulu. --temporal-config menimpanya, dan tmprl --config-path mencetak setiap berkas yang dibacanya beserta ada atau tidaknya, karena “berkas mana yang sebenarnya dibaca” adalah pertanyaan pertama siapa pun saat sebuah profil tidak termuat.

    Uji yang melewati, dan CI yang menolak melewati

    Uji integrasinya dilewati kalau tidak ada server Temporal yang bisa dijangkau, jadi cargo test tetap hijau di mesin yang belum pernah menjalankannya. Di CI, “dilewati” dan “lolos” terlihat sama, jadi TMPRL_REQUIRE_SERVER=1 mengubah pelewatan itu jadi kegagalan. CI memasangnya, menyalakan dev server, mengisinya dengan workflow, dan menjalankan ujinya terhadap dev server dari dua versi CLI temporal, yang terbaru dan v1.5.1.

    Satu catatan build dari tulisan pertama sudah tidak berlaku, dan satu masih. protoc tidak lagi wajib: sejak v0.1.4 proto-nya dikompilasi oleh kompiler Rust murni yang ikut dibawa, jadi toolchain Rust (1.95 atau lebih baru) adalah satu-satunya syarat build. Info debug tetap dimatikan di profil dev, karena proto hasil generasi membuat target/ membengkak kalau info debug menyala; cargo build --profile dbg ada untuk saat debugger memang dibutuhkan.

    Yang belum ada

    Peta jalannya pindah dari README ke docs/ROADMAP.md, diurutkan oleh satu pertanyaan: apa yang menghalangi orang selain penulisnya untuk mengandalkan ini? Yang masih terbuka di sana:

    • tenggat permintaan dan sambung ulang: tidak ada RPC yang punya timeout, dan satu sambungan yang dibuat saat mulai tidak pernah dibuat lagi
    • riwayat besar: tiap halaman yang tiba mengelompokkan ulang semua yang sudah dimuat, dan belum ada benchmark
    • payload untuk signal dan update, QueryWorkflow, dan codec encode untuk apa pun yang dikirim ke namespace terenkripsi
    • batch di sisi server atas sebuah kueri (batch di atas berjalan di sisi klien, baris demi baris)
    • membandingkan dua run, makro, --exec tanpa antarmuka

    Beberapa hal meninggalkan daftar itu ke arah lain. Tema sudah terbit: theme.toml, NO_COLOR, dan palet 16 warna yang mengikuti tema terang atau gelap milik terminalnya. Layar deployment, Nexus, dan arsip sekarang tertulis sebagai tidak direncanakan.

    Tujuh rilis menyusul v0.1.0 (2026-09-17), dan v0.2.1 yang sekarang ada di GitHub, crates.io, dan tap Homebrew:

    brew install arisros/tap/tmprl
    cargo install tmprl          # Rust 1.95 atau lebih baru, tidak ada yang lain

    Tag v* menjalankan cargo-dist: biner Linux dan macOS untuk dua arsitektur, pemasang berbasis shell, formula yang didorong ke tap Homebrew, dan workspace-nya diterbitkan ke crates.io.

    Apakah ia layak ada

    galaxy-io/tempo sudah jalan dan sudah selesai, dan README-nya masih menyarankan memakai itu kalau kamu butuh TUI Temporal sekarang. tmprl membidik hal lain: kesetaraan dengan web UI, dan model editor modal alih-alih menu.

    Di tulisan pertama, perbedaan itu baru niat. Sekarang wujudnya mutasi, jadwal, batch, jalur codec, penjaga hanya-baca, linimasa, dasbor, dan jalan dari sebuah event ke sumbernya. Kesetaraan penuh dengan web UI masih lebih jauh dari yang disiratkan daftar itu, tapi pertanyaan apakah ini layak jadi implementasi kedua akhirnya punya sesuatu untuk dinilai.

    id en
    rss gh in