# πŸ“‹ PRD: tia β€” "Terminal Is A" My Way > **Product Requirements Document** > **Version:** 1.0.0-draft > **Author:** oxpoe > **Created:** 2026-10-15 > **Status:** Draft β€” Menunggu review & approval --- ## 1. Executive Summary **tia** (Terminal Is A β€” my way) adalah aplikasi terminal yang dibangun dengan Go dan ekosistem Charm (charmbracelet), berfungsi sebagai all-in-one Docker management tool langsung dari terminal. tia menggabungkan kemampuan **management & convert dari Dockge** dengan **UI/UX elegance dari lazydocker**, diperkaya dengan audio feedback, animasi ASCII, dashboard beranda yang keren, serta utilitas pelengkap. ### Vision Statement & Tagline ``` "Satu binary untuk semua kebutuhan Docker kamu β€” Terminal Is A My Way" Tagline: "Just Work" ``` ### Kenapa tia? - **Dockge** bagus tapi web-based β€” butuh browser, tidak cocok untuk server headless atau workflow terminal-native. - **lazydocker** bagus tapi pakai library lama (gocui), tidak ada fitur konversi `docker run` β†’ `compose`, dan manajemen stack terbatas. - **tia** mengambil yang terbaik dari keduanya: **modern UI (Charm Bubble Tea v2)** + **manajemen stack lengkap** + **konverter cerdas** + **multi-host** + **audio & animasi ASCII** β€” semuanya dalam satu binary ringkas tanpa dependensi runtime rumit. ### Prinsip Produk: Satu Binary Multifungsi (TUI Utama + CLI Pendamping) tia hadir sebagai **satu binary mandiri (single static binary)** yang fleksibel dengan filosofi **"Just Work"**: 1. **Pengalaman Utama = TUI Interaktif Penuh:** Menjalankan `tia-love` tanpa argumen langsung meluncurkan TUI modern lengkap dengan dashboard keren (logo, jam digital ASCII), animasi dinamis, mouse support penuh, efek suara interaktif, dan notifikasi toast status. 2. **Mode CLI Pendamping (Scriptable & Headless):** Untuk kebutuhan otomatisasi, CI/CD, atau perintah kilat tanpa membuka antarmuka TUI, binary yang sama dapat dipanggil dengan subcommand CLI (misal: `tia-love convert ...`, `tia-love ps`, `tia-love up `, `tia-love doctor`). Seluruh logika inti di-share dari `internal/core`, sehingga output dan perilakunya 100% konsisten. 3. **Instalasi Instan:** Dapat diinstal dengan **1 baris perintah (`curl -fsSL ... | sh`)** atau cukup unduh binary Go precompiled secara manual dan langsung jalankan (`./tia-love`). 4. **Mouse & Keyboard Setara:** Seluruh navigasi dan operasi di TUI ramah mouse (klik, drag, scroll, hover) maupun keyboard shortcut vim-like. 5. **Aset Bebas & Terbuka:** Aset suara (CC0), palet warna (Catppuccin), dan animasi murni open-source serta tertanam (embedded) langsung di dalam binary. --- ## 2. Target Users | User | Use Case | |---|---| | **Homelab enthusiast** | Manage Docker stacks di server rumah via SSH | | **DevOps engineer** | Monitor & manage containers di production/staging | | **Developer** | Quick convert docker run commands, manage dev containers | | **Sysadmin** | Multi-host Docker management tanpa web UI overhead | --- ## 3. Technology Stack | Component | Technology | Version | Alasan | |---|---|---|---| | **Language** | Go | 1.24+ | Performance, single binary, Docker SDK native | | **TUI Framework** | Bubble Tea v2 | `charm.land/bubbletea/v2` | Elm Architecture, Cursed Renderer, modern | | **UI Components** | Bubbles v2 | `charm.land/bubbles/v2` | List, Table, Viewport, TextInput, dll | | **Styling** | Lip Gloss v2 | `charm.land/lipgloss/v2` | CSS-like styling, canvas layering | | **Forms** | Huh v2 | `charm.land/huh/v2` | Interactive forms, setup wizard | | **Markdown** | Glamour v2 | `charm.land/glamour/v2` | Help docs rendering | | **Logging** | Charm Log v2 | `charm.land/log/v2` | Structured logging to file | | **Docker** | Docker SDK for Go | `github.com/docker/docker/client` | Real-time events, stats, management | | **Compose** | Docker Compose CLI | System binary | Compose operations (up/down/pull) | | **YAML** | go-yaml v3 | `gopkg.in/yaml.v3` | Compose file parsing/writing | | **Config** | go-yaml v3 | `gopkg.in/yaml.v3` | Baca/tulis config, diatur lewat layar Pengaturan di TUI (tanpa framework CLI) | | **Audio Engine** | Oto v3 | `github.com/ebitengine/oto/v3` | Pure-Go audio player (`CGO_ENABLED=0`), PulseAudio/PipeWire/ALSA fallback | | **Audio Assets** | Kenney Interface Sounds | CC0 1.0 Universal | Aset audio open-source tanpa royalti, WAV 44.1kHz mono embedded (<2MB) | | **Animation Engine**| Harmonica | `github.com/charmbracelet/harmonica` (v0.2.0) | Fisika pegas (spring physics) & timer ticker 30 FPS untuk animasi TUI | | **CLI Dispatcher** | Native Go Router | Go standard library | Router ringan untuk mode CLI pendamping (`tia-love convert`, `tia-love ps`, dll) | ### Docker Interaction Strategy: Hybrid ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ tia Docker Layer β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ Docker SDK for Go β”‚ docker compose CLI β”‚ β”‚ (Real-time & Direct) β”‚ (Compose Operations) β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β€’ Container list/inspect β”‚ β€’ docker compose up -d β”‚ β”‚ β€’ Image list/inspect β”‚ β€’ docker compose down β”‚ β”‚ β€’ Volume list/inspect β”‚ β€’ docker compose pull β”‚ β”‚ β€’ Network list/inspect β”‚ β€’ docker compose restart β”‚ β”‚ β€’ Container stats stream β”‚ β€’ docker compose logs -f β”‚ β”‚ β€’ Container logs stream β”‚ β€’ docker compose ps β”‚ β”‚ β€’ Docker events stream β”‚ β€’ docker compose ls β”‚ β”‚ β€’ Container start/stop β”‚ β€’ docker compose build β”‚ β”‚ β€’ Container exec β”‚ β€’ docker compose config β”‚ β”‚ β€’ Image pull/remove β”‚ β”‚ β”‚ β€’ System prune β”‚ β”‚ β”‚ β€’ Container update β”‚ β”‚ β”‚ (resource limits) β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` **Alasan hybrid:** - Docker SDK lebih performant untuk real-time operations (events, stats, logs) - Docker Compose CLI lebih reliable untuk compose operations β€” karena compose logic (variable interpolation, .env loading, service ordering, network creation) terlalu complex untuk di-reimplment via raw API - Ini approach yang sama dengan Dockge dan lazydocker --- ## 4. Feature Requirements ### 4.1 Core Features (MVP β€” Phase 1 & 2) #### F-001: Multi-Panel TUI Layout - **Priority:** P0 (Must Have) - **Description:** Layout 2 panel (sidebar + content) dengan responsive sizing, mirip lazydocker - **Acceptance Criteria:** - Sidebar (β…“ width) menampilkan: Stacks, Containers, Images, Volumes, Networks - Content panel (β…” width) menampilkan detail item yang dipilih - Tab navigation di content panel (Logs, Stats, Config, Env, Top) - Responsive saat terminal resize - 3 screen modes: normal (33/67), half (50/50), fullscreen (100% content) #### F-002: Container Management View - **Priority:** P0 - **Description:** List dan inspect semua Docker containers - **Acceptance Criteria:** - List containers dengan status indicator (🟒 running, πŸ”΄ stopped, 🟑 paused) - Show: name, image, status, ports, uptime - Real-time status update via Docker events - Filter/search containers #### F-003: Image, Volume, Network Views - **Priority:** P0 - **Description:** Browse dan inspect Docker resources - **Acceptance Criteria:** - Images: repository, tag, size, created date, in-use status - Volumes: name, driver, mountpoint, size - Networks: name, driver, scope, subnet, attached containers #### F-004: Real-time Log Viewer - **Priority:** P0 - **Description:** Stream container/stack logs real-time - **Acceptance Criteria:** - Real-time log streaming dengan ANSI color support - Scroll through history (viewport) - Toggle timestamps on/off - Search/filter dalam logs (`/`) - Configurable tail lines (default 300) #### F-005: Resource Stats & Graphs - **Priority:** P0 - **Description:** Live CPU, Memory, Network, I/O stats dengan ASCII graphs - **Acceptance Criteria:** - CPU usage percentage + sparkline graph - Memory usage (used/limit) + bar graph - Network I/O (↑ upload, ↓ download rate) - Disk I/O (read/write rate) - PIDs count - Update interval: 1 second - ASCII sparkline characters: `β–β–‚β–ƒβ–„β–…β–†β–‡β–ˆ` #### F-006: Vim-like Navigation & Keybindings - **Priority:** P0 - **Description:** Keyboard-driven navigation - **Keybinding Map:** | Key | Scope | Action | |---|---|---| | `q` / `Ctrl+C` | Global | Quit | | `?` | Global | Toggle help overlay | | `Tab` / `Shift+Tab` | Global | Switch focus sidebar ↔ content | | `j` / `↓` | List | Move down | | `k` / `↑` | List | Move up | | `Enter` | List | Select / Expand | | `h` / `←` | Tabs | Previous tab | | `l` / `β†’` | Tabs | Next tab | | `[` / `]` | Tabs | Previous / Next tab | | `/` | List | Search / Filter | | `Esc` | Modal | Close modal / Cancel | | `1-5` | Global | Jump to section | | `+` / `_` | Global | Cycle screen mode | #### F-022: Full Mouse Support (Mouse-Friendly) - **Priority:** P0 (Must Have β€” berlaku sejak Phase 1, bukan fitur tambahan) - **Description:** tia harus nyaman dipakai hanya dengan mouse, selevel dengan keyboard. Mouse bukan pelengkap, tapi cara interaksi utama yang setara. - **Prinsip desain:** 1. **Parity:** semua aksi yang bisa dilakukan lewat keyboard juga bisa lewat mouse, dan sebaliknya 2. **Discoverable:** elemen klikable terlihat jelas (tombol berlabel, hover highlight, ikon) 3. **Non-destruktif:** aksi destruktif lewat mouse tetap lewat dialog konfirmasi - **Interaksi mouse yang didukung:** | Interaksi | Lokasi | Aksi | |---|---|---| | Klik kiri | Item di sidebar | Pilih item + tampilkan detail | | Klik kiri | Header section sidebar (Stacks/Containers/…) | Expand / collapse section | | Klik kiri | Tab (Logs/Stats/Config/…) | Pindah tab | | Klik kiri | Panel (sidebar/content) | Pindah fokus ke panel tsb | | Double-click | Item container/stack | Aksi default (buka detail/logs fullscreen) | | Klik kanan | Item di list | Context menu (start/stop/restart/exec/remove/…) | | Scroll wheel | List / log / YAML / inspector | Scroll konten (sesuai `mouse_scroll_lines`) | | Scroll wheel | Tab bar | Ganti tab (opsional) | | Klik + drag | Scrollbar | Scroll cepat | | Klik + drag | Border antara sidebar & content | Resize lebar sidebar | | Hover | Item / tombol / tab | Highlight + tooltip singkat (shortcut key) | | Klik kiri | Tombol toolbar/status bar | Jalankan aksi (`β–Ά Start`, `β–  Stop`, `↻ Restart`, `⌨ Exec`, `⟳ Update`, `πŸ—‘ Delete`, `⇄ Convert`) | | Klik kiri | Hint di status bar (`[?] help`, `[q] quit`) | Jalankan aksi hint tersebut | | Klik kiri | Checkbox di list | Multi-select untuk bulk action | | Klik kiri | Tombol/field di modal & form | Fokus field, tekan tombol, pilih opsi | - **Acceptance Criteria:** - Seluruh alur utama dapat diselesaikan **tanpa menyentuh keyboard** (kecuali mengetik teks, mis. paste command ke converter) - **Toolbar aksi klikable** muncul di atas content panel sesuai konteks item terpilih (container/stack/image/volume/network) - Hover highlight pada list item, tab, dan tombol - Klik kanan membuka context menu yang sama dengan keybinding `x` - Sidebar bisa di-resize dengan drag (disimpan di config) - Scroll wheel bekerja di semua area scrollable - Mode **text select** (toggle `m`) untuk menonaktifkan mouse capture sementara agar bisa select & copy teks native terminal; tersedia juga tombol **Copy** + OSC52 clipboard di log/YAML viewer - Mouse dapat dimatikan penuh via config (`mouse_enabled: false`) dan app tetap fungsional via keyboard - Berfungsi di dalam tmux dan SSH session - **Catatan implementasi (high level, tanpa kode):** Bubble Tea mendukung event klik, scroll, dan motion; hit-testing area klik dikelola oleh layout manager (setiap komponen mendaftarkan zona klikable-nya), sehingga perlu direncanakan dari Phase 1 agar tidak refactor besar di belakang. #### F-023: Multi-Bahasa / i18n (Indonesia & English) - **Priority:** P0 (berlaku sejak Phase 1) - **Description:** Seluruh teks UI tersedia dalam **Bahasa Indonesia (default)** dan **English**. Bahasa dapat dipilih di setup wizard dan diubah kapan saja lewat config atau menu pengaturan, tanpa restart. - **Acceptance Criteria:** - Default bahasa: Indonesia (`language: id`); fallback otomatis ke English jika kunci terjemahan belum ada - Katalog bahasa disimpan sebagai file YAML (`id.yaml`, `en.yaml`) dan di-embed ke dalam binary (tetap single binary) - **Tidak ada string UI yang di-hardcode**: label, tombol, tab, dialog, pesan error, dan hint status bar semuanya lewat katalog - Bahasa dipilih di langkah pertama wizard, dan bisa diganti lewat config (`ui.language`) atau menu pengaturan dengan efek langsung - Bahasa dapat diganti kapan saja dari **layar Pengaturan** di dalam tia (lihat 5.1.5); tidak ada flag atau env var yang diperlukan - Istilah teknis yang sudah umum **tidak diterjemahkan**: `Env`, `Image`, `Volume`, `Stack`, `Shell`, `CPU`, `RAM`, `PID`, `Log` - Tidak diterjemahkan juga: output log container, nama flag docker, isi file YAML - Lebar kolom/tombol tidak boleh rusak karena teks Indonesia lebih panjang (layout dihitung dari panjang teks, bukan lebar tetap) - Struktur katalog mudah ditambah bahasa baru di masa depan (cukup tambah file `.yaml`) - Pesan error dari Docker/CLI tetap ditampilkan asli, dengan penjelasan singkat berbahasa terpilih di atasnya **Contoh pemetaan istilah:** | Kunci | Indonesia | English | |---|---|---| | `section.stacks` | Stack | Stacks | | `section.containers` | Kontainer | Containers | | `section.networks` | Jaringan | Networks | | `tab.logs` | Log | Logs | | `tab.stats` | Statistik | Stats | | `tab.config` | Konfigurasi | Config | | `tab.processes` | Proses | Top | | `action.start` | Mulai | Start | | `action.stop` | Hentikan | Stop | | `action.restart` | Mulai ulang | Restart | | `action.pause` | Jeda | Pause | | `action.remove` | Hapus | Remove | | `action.update` | Perbarui | Update | | `state.running` | berjalan | running | | `state.stopped` | berhenti | stopped | | `state.healthy` | sehat | healthy | #### F-024: Audio Feedback & Sound Effects - **Priority:** P0 (berlaku sejak Phase 1) - **Description:** Setiap interaksi pengguna (klik mouse, navigasi keyboard, buka modal, dismiss, eksekusi perintah, notifikasi status) memberikan umpan balik suara yang menyenangkan dan memuaskan (*tactile feel*). - **Interaksi & Kejadian Bersuara:** - `click.wav`: Saat mengklik tombol toolbar, baris list, tab, atau checkbox. - `navigate.wav`: Saat memindahkan kursor navigasi (`j`/`k` atau panah) di daftar. - `modal_open.wav`: Saat modal dialog terbuka (konverter, prune, pengaturan). - `modal_close.wav`: Saat modal ditutup atau dibatalkan. - `notify_success.wav`: Saat operasi berhasil (stack running, konversi sukses, prune tuntas). - `notify_warning.wav`: Saat muncul peringatan atau konfirmasi aksi destruktif (misal: hapus kontainer). - `notify_error.wav`: Saat perintah gagal, koneksi daemon putus, atau syntax error. - `exec.wav`: Saat memicu shell exec atau trigger rebuild. - **Acceptance Criteria:** - Menggunakan library audio pure-Go `github.com/ebitengine/oto/v3` (`CGO_ENABLED=0`), tanpa kompilasi CGO dan tanpa merusak sifat single binary mandiri. - Seluruh aset audio bersumber dari lisensi terbuka **CC0 (Kenney Interface Sounds / UI Audio)**, dikonversi ke WAV (mono 44.1kHz, 16-bit), total ukuran < 2 MB, di-embed lewat `go:embed`. - Inisialisasi audio asynchronous (tidak memperlambat waktu startup aplikasi < 500ms). - Dilengkapi kontrol penuh di Layar Pengaturan: - Toggle On/Off efek suara (`ui.sound_enabled: true/false`). - Pengatur volume (0% - 100%). - Mute otomatis jika mendeteksi sesi SSH (dengan opsi override aktif manual). - Degradasi anggun (*graceful fallback*): jika mesin tidak memiliki audio driver/server aktif (misal container atau headless tanpa sound card), aplikasi tetap berjalan 100% normal tanpa panik/crash. - Seluruh sinyal audio **selalu memiliki padanan visual** (toast, status badge, warna Catppuccin). #### F-025: Top-Center Status Toast Notifications - **Priority:** P0 (berlaku sejak Phase 1) - **Description:** Setiap notifikasi status aplikasi muncul sebagai pop-up (toast) animasi elegan yang meluncur dari **tengah atas layar** (*top-center*), lengkap dengan status badge, ikon, dan deskripsi kejadian. - **Kategori Status Notifikasi:** 1. `[ SUKSES ]` (Hijau/Green): Aksi berhasil (contoh: *Kontainer 'api' berhasil dimulai*, *Konversi docker run tersimpan ke ~/.tia/stacks/web*). 2. `[ PERINGATAN ]` (Kuning/Yellow): Butuh perhatian (contoh: *Penyimpanan Docker tersisa < 10%*, *Port 8080 bertabrakan*). 3. `[ GAGAL ]` (Merah/Red): Error/kegagalan (contoh: *Gagal menarik image nginx:latest - timeout*, *Docker daemon tidak merespons*). 4. `[ INFO ]` (Biru/Blue): Pemberitahuan informasional (contoh: *Host remote 'prod-srv' terhubung*, *Mode tema diubah ke Latte*). - **Acceptance Criteria:** - Posisi selalu berada di tengah atas viewport terminal (`x: center`, `y: 0` atau `y: 1`). - Animasi transisi slide-in lembut saat muncul dan slide-out saat hilang. - Dilengkapi auto-dismiss timer (default: 4 detik), durasi dapat dihentikan saat mouse di-hover di atasnya. - Tombol tutup cepat (`βœ•`) yang bisa diklik mouse atau ditekan `Esc` untuk menutup seketika. - Sistem antrean (*toast queue*): jika ada beberapa event masuk serentak, notifikasi diantrekan secara berurutan atau ditumpuk rapi tanpa menutupi layar kerja secara agresif. - Mendukung klik langsung pada toast untuk menuju ke resource terkait (misal: klik toast error container -> langsung fokus ke container tersebut dan buka tab Log). #### F-026: Animasi ASCII & Efek Visual Dinamis - **Priority:** P0 (berlaku sejak Phase 1) - **Description:** Menghadirkan animasi ASCII yang hidup, estetik, dan halus (*charming*) untuk memperkuat identitas TUI modern tanpa membebani CPU. - **Elemen Animasi:** 1. **Splash Screen / Animated Logo:** Saat aplikasi start pertama kali atau membuka Beranda, logo ASCII `tia` muncul dengan efek ketikan/glitch/shimmer halus. 2. **Real-time Live Digital Clock:** Jam digital format ASCII dinamis yang berdetik setiap detik di pojok dashboard beranda. 3. **Pulsing Status Indicators:** Indikator titik status kontainer berkedip/bernapas lembut (pulsing `●`) untuk kontainer yang sedang dalam masa transisi (*starting*, *restarting*). 4. **Smooth Progress Bars & Spinners:** Visual progress bar pengunduhan image dan spinner elegan dari Charm saat memproses operasi latar belakang. 5. **Animated Sparklines:** Grafik telemetri CPU & Memory yang mengalir halus secara real-time. - **Acceptance Criteria:** - Framerate dibatasi maksimal 30 FPS untuk menjaga efisiensi daya dan CPU (< 3% idle CPU usage). - Ditenagai oleh `github.com/charmbracelet/harmonica` (spring physics) untuk fisika transisi dan `tea.Tick` untuk timer event. - Mode *Reduced Motion / Non-Animated*: opsi di layar Pengaturan untuk mematikan animasi bagi pengguna yang menginginkan tampilan statis atau berada di koneksi SSH dengan bandwidth sangat rendah. #### F-027: Dashboard Beranda Keren (Home Dashboard View) - **Priority:** P0 (berlaku sejak Phase 1) - **Description:** Layar sambutan / beranda komprehensif yang menampilkan status menyeluruh ekosistem Docker lokal/remote, jam real-time, logo ASCII, serta pintasan aksi cepat. - **Komponen Dashboard Beranda:** - **Header Hero:** Seni ASCII Logo `tia` bertuliskan *Terminal Is A My Way* + Tagline *Just Work* dengan warna aksen Catppuccin. - **Live Digital Clock Widget:** Jam digital ASCII besar (`HH:MM:SS`) beserta penanggalan lengkap dan zona waktu lokal. - **Docker Engine Overview Card:** Versi Docker daemon, API version, status socket, total memory/CPU host, uptime. - **Quick Resource Counters:** Kotak metrik ringkas: Total Stack (Aktif/Mati), Kontainer (Berjalan/Berhenti), Total Image, Volume, & Jaringan. - **Quick Actions Launcher:** Tombol pintas klikable untuk aksi favorit: `[ ⇄ Konversi Baru ]`, `[ 🧹 Bersihkan Sistem ]`, `[ βž• Buat Stack ]`, `[ βš™ Pengaturan ]`, `[ 🌐 Ganti Host ]`. - **Recent Activity Feed:** 5 peristiwa Docker terkini (kontainer baru start, image di-pull, error terakhir). - **Acceptance Criteria:** - Tampil saat aplikasi baru pertama kali dibuka, atau dapat diakses kapan saja dengan menekan `0` atau mengklik ikon Beranda di header. - Seluruh kartu statistik dan tombol aksi dapat diklik dengan mouse. - Tata letak responsif menyesuaikan ukuran jendela terminal. #### F-028: Satu Binary Multifungsi & CLI Companion Mode - **Priority:** P0 (arsitektur fondasi) - **Description:** `tia-love` adalah satu file binary mandiri (single binary) yang multifungsi. Secara default `tia-love` membuka TUI interaktif penuh, namun dapat dipanggil langsung dari command line (CLI mode) untuk eksekusi skrip, CI/CD, atau konversi cepat tanpa membuka TUI. - **Subcommand CLI Pendamping:** - `tia-love`: Meluncurkan antarmuka TUI interaktif penuh. - `tia-love convert [flags/command]`: Mengonversi perintah `docker run` menjadi compose YAML dan mencetaknya ke stdout atau menyimpannya langsung ke direktori stack (contoh: `tia-love convert "docker run -d -p 80:80 nginx"`). - `tia-love ps`: Menampilkan ringkasan status semua stack & kontainer dalam format tabel rapi atau JSON (`--json`). - `tia-love up `: Menjalankan stack di background tanpa membuka TUI. - `tia-love down `: Menghentikan & menurunkan stack. - `tia-love update `: Menarik image terbaru dan merefresh kontainer stack via CLI. - `tia-love doctor`: Memeriksa kesehatan sistem (koneksi Docker daemon, ketersediaan sound server/driver, versi Go, direktori stack). - `tia-love version` / `tia-love --version`: Menampilkan versi, commit git, dan build info. - **Acceptance Criteria:** - Berbagi basis kode logika inti yang sama di `internal/core`, menjamin kesamaan hasil antara eksekusi di TUI dan CLI. - Kode keluar (*exit codes*) standar (0 = sukses, >0 = error) untuk integrasi skrip bash. - Format output CLI mendukung `--json` untuk parsing oleh `jq` atau tool otomatisasi lainnya. - Tetap terkompilasi sebagai satu binary statis tanpa ketergantungan library eksternal. #### F-029: 1-Line Installer & Standalone Binary Distribution - **Priority:** P0 (distribusi rilis) - **Description:** Pengguna dapat memasang `tia-love` dalam hitungan detik menggunakan perintah instalasi satu baris (*one-line command*) otomatis, atau dengan mengunduh binary Go mandiri tanpa proses kompilasi manual. - **Metode Instalasi:** 1. **One-Line Command (Rekomendasi):** ```bash curl -fsSL https://gitea.oxpoe.qzz.io/oxpoe/tia-love/raw/branch/main/install.sh | sh ``` - Skrip otomatis mendeteksi OS (Linux, macOS) dan arsitektur CPU (`amd64`, `arm64`). - Mengunduh rilis tarball terbaru dari Gitea Releases (gitea.oxpoe.qzz.io). - Memverifikasi checksum SHA256 secara otomatis demi keamanan sebelum mengekstrak. - Memasang binary ke direktori pengguna (`~/.local/bin/tia-love` tanpa memerlukan akses `sudo`). - Memberikan instruksi jika `~/.local/bin` belum ada di `$PATH`. 2. **Manual Download Precompiled Binary:** - Pengguna dapat langsung menuju halaman Releases di Gitea (https://gitea.oxpoe.qzz.io/oxpoe/tia-love/releases), mengunduh file binary terkompresi (misal: `tia-love_linux_amd64.tar.gz`), mengekstraknya, dan langsung menjalankannya (`./tia-love`). 3. **Go Install (untuk developer Go):** ```bash go install gitea.oxpoe.qzz.io/oxpoe/tia-love/cmd/tia-love@latest ``` - **Acceptance Criteria:** - Skrip instalasi aman (`set -euo pipefail`), transparan, dan tidak meminta privilege root/sudo secara membabi-buta. - Rilis otomatis di-bundle via GoReleaser dengan SHA256 checksums file. --- ### 4.2 Stack Management & Converter (Phase 3) #### F-007: Stacks Directory Management - **Priority:** P0 - **Description:** Manage Docker Compose stacks dengan filesystem-based approach - **Stacks Strategy:** 1. Saat setup pertama, user menentukan stacks directory (default: `~/.tia/stacks/`) 2. tia scan system untuk existing compose files (`docker compose ls --all`) 3. Existing stacks bisa di-copy/move ke stacks directory 4. Semua managed stacks ada dalam 1 folder yang ditentukan saat setup - **Acceptance Criteria:** - Setup wizard saat pertama run - Scan dan discover existing compose stacks - Import/migrate stacks ke managed directory - Stack status: Active (🟒), Exited (πŸ”΄), Inactive (βšͺ) - Stack CRUD: create, start, stop, restart, down, delete, update #### F-008: Docker Run β†’ Docker Compose Converter - **Priority:** P0 - **Description:** Convert `docker run` commands menjadi `docker-compose.yml` - **Supported docker run flags:** | Flag | Compose Mapping | |---|---| | `--name` | `container_name` | | `-p` / `--publish` | `ports` | | `-v` / `--volume` | `volumes` | | `--mount` | `volumes` (long syntax) | | `-e` / `--env` | `environment` | | `--env-file` | `env_file` | | `--restart` | `restart` | | `--network` | `networks` | | `--memory` / `-m` | `deploy.resources.limits.memory` | | `--cpus` | `deploy.resources.limits.cpus` | | `-d` / `--detach` | (implied) | | `--hostname` | `hostname` | | `--entrypoint` | `entrypoint` | | (trailing args) | `command` | | `--user` / `-u` | `user` | | `--workdir` / `-w` | `working_dir` | | `--label` / `-l` | `labels` | | `--cap-add` | `cap_add` | | `--cap-drop` | `cap_drop` | | `--privileged` | `privileged` | | `--pid` | `pid` | | `--dns` | `dns` | | `--log-driver` | `logging.driver` | | `--log-opt` | `logging.options` | | `--tmpfs` | `tmpfs` | | `--device` | `devices` | | `--health-cmd` | `healthcheck.test` | | `--health-interval` | `healthcheck.interval` | | `--health-timeout` | `healthcheck.timeout` | | `--health-retries` | `healthcheck.retries` | | `--shm-size` | `shm_size` | | `--init` | `init` | | `--read-only` | `read_only` | | `--stop-signal` | `stop_signal` | | `--stop-grace-period` | `stop_grace_period` | - **Acceptance Criteria:** - Modal UI: paste docker run β†’ preview YAML β†’ edit β†’ save as stack - Support multi-line commands (backslash continuation) - Handle quoted strings dan special characters - Generate valid compose YAML - Option: append to existing stack or create new #### F-009: Compose YAML Editor - **Priority:** P1 (Should Have) - **Description:** View dan edit compose.yaml dari dalam tia - **Acceptance Criteria:** - YAML viewer dengan syntax highlighting (via glamour) - **Editor YAML bawaan di dalam tia** (area teks multi-baris, syntax highlighting, nomor baris, validasi YAML live), bisa dioperasikan dengan keyboard dan mouse - Tombol `[ Simpan ]`, `[ Batal ]`, dan `[ Validasi ]` yang bisa diklik - Editor eksternal bersifat **opsional** (vim/nano/helix lewat pengaturan): TUI di-suspend sementara lalu kembali otomatis - Editor `.env` dengan cara yang sama (bawaan di tia) - Compose validation (`docker compose config`) #### F-010: Stack Update - **Priority:** P0 - **Description:** Update stack (pull latest images + recreate containers) - **Acceptance Criteria:** - Pull latest images untuk semua services in stack - Recreate containers dengan images baru - Show progress (pull progress, recreating status) - Option: update single service atau seluruh stack --- ### 4.3 Container Actions (Phase 4) #### F-011: Container Exec (Shell) - **Priority:** P0 - **Description:** Exec shell into running container - **Acceptance Criteria:** - Suspend TUI β†’ attach ke container shell β†’ resume TUI saat exit - Auto-detect shell (`/bin/bash`, `/bin/sh`, `/bin/ash`) - Menggunakan `tea.ExecProcess()` untuk clean suspension - Keybinding: `e` pada container yang dipilih #### F-012: Container Lifecycle Actions - **Priority:** P0 - **Description:** Full container lifecycle management - **Acceptance Criteria:** - Start, Stop, Restart, Pause, Unpause, Remove, Rename - Confirmation dialog untuk destructive actions (remove) - Bulk actions: select multiple β†’ apply action - Context menu (`x`) untuk semua available actions #### F-013: Bulk Operations - **Priority:** P1 - **Description:** Batch operations pada multiple resources - **Acceptance Criteria:** - Select multiple containers/images/volumes - Apply: stop all, remove all, restart all - Confirmation with summary sebelum execute --- ### 4.4 Advanced Features (Phase 5) #### F-014: System Prune - **Priority:** P1 - **Description:** Cleanup unused Docker resources - **Acceptance Criteria:** - Interactive prune dialog - Preview: reclaimable space per category - Categories: stopped containers, dangling images, unused images, unused volumes, unused networks, build cache - Selective prune (pilih kategori) - Summary setelah prune (space reclaimed) #### F-015: Container Health Check Monitor - **Priority:** P1 - **Description:** Monitor container health checks - **Acceptance Criteria:** - Health status indicators: 🟒 healthy, 🟑 starting, πŸ”΄ unhealthy, βšͺ none - Health check command, interval, timeout, retries - Health check log history - Alert/highlight unhealthy containers #### F-016: Resource Limits Editor - **Priority:** P2 (Nice to Have) - **Description:** Edit container resource limits on-the-fly - **Acceptance Criteria:** - Form (via huh) untuk set/modify: memory limit, CPU limit, pids limit - Uses Docker SDK `ContainerUpdate()` - Show current vs new values #### F-017: Dockerfile Builder/Editor - **Priority:** P2 - **Description:** Basic Dockerfile template editor - **Acceptance Criteria:** - Dockerfile templates (FROM, RUN, COPY, EXPOSE, CMD, etc.) - Editor Dockerfile bawaan di dalam tia (opsional: buka di editor eksternal lalu kembali ke TUI) - Build integration: `docker build` dari dalam tia - Build progress streaming #### F-018: Docker Registry Browser - **Priority:** P2 - **Description:** Browse Docker Hub dan search images - **Acceptance Criteria:** - Search images on Docker Hub (via Registry HTTP API v2) - View available tags - Pull image langsung dari browser - Show image description, stars, pulls #### F-019: Export/Import Stacks - **Priority:** P1 - **Description:** Export dan import compose stacks - **Acceptance Criteria:** - Export: pack `compose.yaml` + `.env` + configs β†’ `.tar.gz` - Import: extract archive β†’ create stack in stacks directory - Portable format #### F-020: Volume Backup & Restore - **Priority:** P1 - **Description:** Backup dan restore named Docker volumes - **Acceptance Criteria:** - Backup: volume β†’ `.tar.gz` (via temporary alpine container) - Restore: `.tar.gz` β†’ volume - Backup strategy: ``` docker run --rm -v :/data -v :/backup alpine \ tar czf /backup/-.tar.gz -C /data . ``` - List available backups - Selective restore --- ### 4.5 Multi-Host Support (Phase 6) #### F-021: Multi-Host Docker Management - **Priority:** P1 - **Description:** Manage Docker pada multiple remote servers via SSH - **Acceptance Criteria:** - Add/remove/edit remote hosts - SSH tunnel ke remote Docker socket - Host selector di sidebar (switch antar hosts) - Semua fitur bekerja di remote host (containers, stacks, images, etc.) - Host config: name, address, SSH key path, port, user - Connection status indicator per host - Config persistence di `~/.config/tia/hosts.yaml` --- ## 5. UI/UX Design ### 5.1.0 Layar Beranda (Home Dashboard View) β€” Jam Digital ASCII, Metrik & Pintasan Layar pembuka interaktif yang menampilkan identitas keren `tia` ("Terminal Is A My Way" - Tagline: "Just Work"), jam digital ASCII dinamis, status ringkas ekosistem Docker, dan pintasan aksi cepat: ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β–“ tia Β· terminal is a Tagline: Just Work ● lokal β–Ύ β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ _ _ β”‚ β”‚ | |_(_) __ _ ╔╦╗╦╔═╗ Terminal Is A My Way β”Œβ”€β”€β”€ JAM LOKAL ────┐ β”‚ β”‚ | __| |/ _` | β•‘ ║╠═╣ v0.1.0 (Catppuccin Mocha) β”‚ β–ˆβ–ˆ β–ˆβ–€β–ˆ β–ˆ β–ˆ β–ˆβ–€β–ˆ β”‚ β”‚ β”‚ |_| |_|\__,_| β•© β•©β•© β•© Engine: Docker 27.2.0 (API 1.47β”‚ β–ˆβ–ˆ β–ˆβ–„β–ˆ β–ˆβ–€β–ˆ β–ˆβ–„β–ˆ β”‚ β”‚ β”‚ β”‚ WIB (UTC+7) β”‚ β”‚ β”‚ β”Œβ”€ STATUS EKOSISTEM DOCKER ─────────────────────────┐ β”‚ 15 Okt 2026 β”‚ β”‚ β”‚ β”‚ πŸ“¦ Stacks : 3 Total (● 2 Aktif, β—‹ 1 Berhenti) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ 🐳 Kontainer : 8 Total (● 5 Berjalan, β—‹ 3 Mati) β”‚ β”‚ β”‚ β”‚ πŸ–ΌοΈ Image : 14 Buah (1.42 GB digunakan) β”‚ β”Œβ”€ RESOURCE HOST ───┐ β”‚ β”‚ β”‚ πŸ’Ύ Volume : 6 Buah (340 MB) β”‚ β”‚ CPU : [β–ˆβ–ˆβ–ˆβ–‘β–‘] 28% β”‚ β”‚ β”‚ β”‚ 🌐 Jaringan : 4 Jaringan (bridge, host, app-net) β”‚ β”‚ RAM : 4.2G/16G β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”Œβ”€ PINTASAN AKSI CEPAT (Klik mouse atau tekan shortcut) ───────────────────┐ β”‚ β”‚ β”‚ [ ⇄ Konversi (c) ] [ βž• Stack Baru (n) ] [ 🧹 Prune (P) ] [ βš™ Set (,) ]β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”Œβ”€ AKTIVITAS TERKINI (Log Event Docker) ───────────────────────────────────┐ β”‚ β”‚ β”‚ 05:42:10 [kontainer] 'api' health status: healthy β”‚ β”‚ β”‚ β”‚ 05:40:02 [stack] 'web-app' diperbarui (pull image sukses) β”‚ β”‚ β”‚ β”‚ 05:38:15 [image] 'postgres:16-alpine' di-pull selesai β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ [Enter] Masuk Workspace [0] Beranda [?] Bantuan [q] Keluar β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ### 5.1 Workspace Utama (Resource Management & Inspection) > Bahasa UI default: **Indonesia** (opsi English, lihat F-023). Istilah teknis (`Env`, `Image`, `Volume`, `Stack`, `Shell`) tidak diterjemahkan. Pesan log container ditampilkan apa adanya. ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β–“ tia Β· terminal is a ● lokal β–Ύ v0.1.0 β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β–Ύ Stack (3) β”‚ [Log] Statistik Konfigurasi Env Proses β”‚ β”‚ ● web-app β”‚ [β–  Berhenti] [↻ Mulai Ulang] [⌨ Shell] [⏸ Jeda] β”‚ β”‚ ● database β”‚ ───────────────────────────────────────────────────── β”‚ β”‚ β—‹ redis β”‚ 05:17:08 INFO Starting server... β”‚ β”‚ β–Ύ Kontainer (5) β”‚ 05:17:09 INFO Listening on :8080 β”‚ β”‚ ● nginx β”‚ 05:17:10 INFO DB connected β”‚ β”‚ β–Ά ● api β”‚ 05:17:11 WARN Cache miss rate 40% β”‚ β”‚ ● postgres β”‚ 05:17:12 INFO GET /health 200 2ms β”‚ β”‚ ● worker β”‚ 05:17:13 ERRO timeout: redis:6379 β”‚ β”‚ β—‹ redis β”‚ 05:17:14 INFO retrying (1/3)... β”‚ β”‚ β–Έ Image (12) β”‚ 05:17:15 INFO redis reconnected β”‚ β”‚ β–Έ Volume (8) β”‚ β”‚ β”‚ β–Έ Jaringan (4) β”‚ β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ [?]bantuan [c]konversi [n]baru [P]bersihkan [m]pilih-teks [/]cari [q]keluar β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ baris ter-highlight = terpilih ● berjalan β—‹ berhenti β–Ύ/β–Έ = buka/tutup bagian Mouse: klik item/tab/tombol Β· klik kanan = menu Β· scroll Β· seret batas = ubah lebar Semua elemen [..] di toolbar & status bar bisa diklik. ``` ### 5.1.1 Tab Statistik ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Log [Statistik] Konfigurasi Env Proses β”‚ β”‚ β”‚ β”‚ CPU β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘ 45.2% β”‚ β”‚ RAM β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘ 312M / 1.0G β”‚ β”‚ β”‚ β”‚ Riwayat CPU (60 dtk) β”‚ β”‚ β–β–‚β–ƒβ–„β–…β–†β–‡β–ˆβ–‡β–†β–…β–„β–ƒβ–‚β–β–‚β–ƒβ–„β–…β–†β–‡β–†β–…β–„β–ƒβ–‚β–β–β–‚β–ƒ β”‚ β”‚ β”‚ β”‚ NET ↑ 1.2 MB/s ↓ 340 KB/s β”‚ β”‚ Disk Baca 2.1 MB/s Tulis 890 KB/s β”‚ β”‚ PIDs 24 β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ### 5.1.2 Detail Stack ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ [Layanan] Konfigurasi Env Log β”‚ β”‚ [β–Ά Jalankan] [β–  Henti] [↻ Ulang] [⟳ Perbarui] [✎ Edit] β”‚ β”‚ ────────────────────────────────────────────────────────── β”‚ β”‚ LAYANAN IMAGE STATUS PORT β”‚ β”‚ web nginx:1.27 ● berjalan 8080β†’80 β”‚ β”‚ app myapp:latest ● berjalan 3000β†’3000 β”‚ β”‚ db postgres:16 ● sehat 5432 β”‚ β”‚ cache redis:7 β—‹ berhenti - β”‚ β”‚ β”‚ β”‚ Pembaruan terakhir: 2 hari lalu Tersedia update: 2 β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ### 5.1.3 Modal Konversi `docker run` β†’ compose ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ ⇄ Konversi docker run β†’ compose βœ• β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ Tempel perintah docker run: β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ docker run -d --name web -p 8080:80 \ β”‚ β”‚ β”‚ β”‚ -v ./html:/usr/share/nginx/html:ro \ β”‚ β”‚ β”‚ β”‚ -e TZ=Asia/Jakarta --restart unless-stopped \ β”‚ β”‚ β”‚ β”‚ nginx:latest β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ Pratinjau (compose.yaml): β”‚ β”‚ β”‚ services: β”‚ β”‚ β”‚ β”‚ web: β”‚ β”‚ β”‚ β”‚ image: nginx:latest β”‚ β”‚ β”‚ β”‚ container_name: web β”‚ β”‚ β”‚ β”‚ ports: ["8080:80"] β”‚ β”‚ β”‚ β”‚ volumes: ["./html:/usr/share/nginx/html:ro"] β”‚ β”‚ β”‚ β”‚ environment: [TZ=Asia/Jakarta] β”‚ β”‚ β”‚ β”‚ restart: unless-stopped β”‚ β”‚ β”‚ β”‚ β”‚ Simpan: (β€’) Stack baru [ web ] ( ) Tambah β”‚ β”‚ β”‚ β”‚ [ Salin YAML ] [ Simpan & Jalankan ] [ Batal ] β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ### 5.1.4 Menu Klik Kanan & Dialog Konfirmasi ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β–Ά Mulai β”‚ β”‚ Hapus kontainer? β”‚ β”‚ β–  Hentikan β”‚ β”‚ β”‚ β”‚ ↻ Mulai ulang β”‚ β”‚ Kontainer "api" akan dihapus. β”‚ β”‚ ⏸ Jeda β”‚ β”‚ Volume tetap disimpan. β”‚ β”‚ ⌨ Buka shell β”‚ β”‚ β”‚ β”‚ ≣ Lihat log β”‚ β”‚ [ Hapus ] [ Batal ] β”‚ β”‚ ⟳ Perbarui image β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ ✎ Ganti nama β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ βœ• Hapus β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ### 5.1.5 Layar Pengaturan (dibuka dengan `,` atau menu βš™ di header) Semua pengaturan diubah **dari dalam tia**, tanpa flag CLI, env var, atau edit file manual. Perubahan bahasa, tema, suara, dan animasi langsung berlaku seketika. ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ βš™ Pengaturan βœ• β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ Bahasa [ Indonesia β–Ύ ] β”‚ β”‚ Mode tema [ Otomatis β–Ύ ] β”‚ β”‚ Warna aksen [ mauve β–Ύ ] β”‚ β”‚ Direktori stack [ ~/.tia/stacks ] β”‚ β”‚ β”‚ β”‚ [x] Efek suara interaktif (klik, modal, alert, notif) β”‚ β”‚ Volume audio [ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘ 80% ] β”‚ β”‚ [x] Mute suara otomatis saat koneksi SSH β”‚ β”‚ [x] Animasi ASCII dinamis (logo shimmer, clock, 30 FPS) β”‚ β”‚ [x] Tampilkan timestamp log β”‚ β”‚ [x] Aktifkan navigasi mouse β”‚ β”‚ [x] Efek hover highlight mouse β”‚ β”‚ β”‚ β”‚ Perubahan berlaku langsung tanpa restart. β”‚ β”‚ β”‚ β”‚ [ Simpan ] [ Batal ] β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ### 5.1.6 Notifikasi Toast Melayang (Top-Center Status Popup) Notifikasi status meluncur halus dari **tengah atas layar** (*top-center*), lengkap dengan status badge berwarna Catppuccin, ikon, deskripsi peristiwa, dan tombol tutup cepat `βœ•`: ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ βœ” [ SUKSES ] Konversi Berhasil Disimpan βœ•β”‚ β”‚ Stack 'web-app' tersimpan di ~/.tia/stacks/web-app/ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ ⚠ [ PERINGATAN ] Port 8080 Bentrok βœ•β”‚ β”‚ Kontainer 'nginx' gagal bind port: sudah dipakai 'api' β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ βœ– [ GAGAL ] Docker Daemon Putus βœ•β”‚ β”‚ Gagal menghubungi /var/run/docker.sock - periksa servisβ”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β„Ή [ INFO ] Host Remote Terhubung βœ•β”‚ β”‚ Berhasil membuka SSH tunnel ke node 'prod-server-01' β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` > Setup wizard pertama kali ada di bagian 7.3. ### 5.2 Detail Tabs per Resource | Sidebar Section | Available Tabs | Content | |---|---|---| | **Stacks** | Logs, Services, Config, Env | Stack logs, service list, compose.yaml, .env | | **Containers** | Logs, Stats, Config, Env, Top | Container logs, resource stats, inspect JSON, env vars, processes | | **Images** | Config, Layers | Image inspect, Dockerfile layers/history | | **Volumes** | Config | Volume inspect, mountpoint, driver | | **Networks** | Config | Network inspect, IPAM, attached containers | ### 5.3 Modal System Modals digunakan untuk: - **Confirm Dialog:** Destructive actions (delete, prune, remove) - **Input Dialog:** Search, filter, rename - **Form Dialog:** Stack creation wizard, resource limits editor, host config (via huh) - **Converter Dialog:** docker run β†’ compose converter - **Help Overlay:** Full keybinding reference **Mouse pada modal:** semua modal punya tombol klikable (`[ OK ]`, `[ Cancel ]`, `[ Save ]`), tombol close `βœ•` di pojok, klik di luar modal = tutup (kecuali form yang belum disimpan β†’ minta konfirmasi), field form bisa difokuskan dengan klik, dan list/select bisa dipilih dengan klik. ### 5.4 Theme System: Catppuccin **Keputusan:** tia memakai **Catppuccin** sebagai satu-satunya tema bawaan (v1). Tema lain (Dracula, Tokyo Night, dll.) tidak masuk v1. #### Mode tema | Mode | Perilaku | |---|---| | `auto` (default) | Deteksi background terminal saat start β†’ **Mocha** (gelap) atau **Latte** (terang) | | `dark` | Paksa **Catppuccin Mocha** | | `light` | Paksa **Catppuccin Latte** | | `terminal` | Pakai **palet ANSI terminal pengguna** (16 warna) agar tia otomatis serasi dengan tema terminal yang sudah dipakai | - Mode bisa diganti saat runtime lewat menu pengaturan atau keybinding (tanpa restart) - Mode diganti lewat **layar Pengaturan** di dalam tia, atau tombol cepat `T` untuk berganti mode (Otomatis β†’ Gelap β†’ Terang β†’ Terminal) - Warna **aksen** dapat dipilih (default `mauve`), mengikuti 14 warna aksen Catppuccin #### Arsitektur warna: token semantik Komponen UI **tidak boleh memakai kode warna langsung**. Semuanya lewat token semantik yang dipetakan ke palet aktif, supaya ganti mode tidak mengubah komponen apa pun: | Token | Dipakai untuk | Mocha (gelap) | Latte (terang) | |---|---|---|---| | `base` | Background utama | Base | Base | | `surface` | Panel, modal, toolbar | Surface0 | Surface0 | | `overlay` | Border, separator | Overlay0 | Overlay0 | | `text` | Teks utama | Text | Text | | `subtext` | Teks sekunder, hint | Subtext0 | Subtext0 | | `accent` | Fokus, tab aktif, item terpilih | Mauve (default) | Mauve (default) | | `success` | ● berjalan, sehat | Green | Green | | `warning` | ⏸ jeda, WARN, memulai | Yellow | Yellow | | `danger` | β—‹ berhenti, ERRO, unhealthy, tombol Hapus | Red | Red | | `info` | INFO, link, port | Blue | Blue | | `hover` | Highlight saat mouse hover | Surface1 | Surface1 | | `selection` | Item terpilih | Surface2 | Surface2 | #### Mode `terminal` - Token dipetakan ke warna ANSI terminal (mis. `success` β†’ ANSI hijau, `danger` β†’ ANSI merah, `accent` β†’ ANSI magenta) - Background tidak diubah (memakai background terminal), hanya warna foreground dan aksen - Cocok untuk pengguna yang sudah memasang Catppuccin (atau tema lain) di terminal mereka #### Acceptance Criteria - Semua komponen (sidebar, tab, toolbar, log, grafik, modal, menu, wizard) terbaca jelas di Mocha, Latte, dan mode terminal - Kontras teks memenuhi keterbacaan (tidak ada teks pudar di Latte) - Level log berwarna: `INFO`=info, `WARN`=warning, `ERRO`=danger - Grafik CPU/RAM berubah warna sesuai beban: hijau (<60%), kuning (60–85%), merah (>85%) - Fallback otomatis ke 256/16 warna jika terminal tidak mendukung truecolor - Jika deteksi background gagal, `auto` jatuh ke Mocha (gelap) - Ganti mode saat runtime langsung berlaku tanpa restart - Mode `terminal` tetap terbaca di terminal dengan palet apa pun > **Catatan:** Catppuccin juga punya flavor FrappΓ© dan Macchiato (gelap menengah). Tidak masuk v1, bisa ditambahkan nanti hanya dengan menambah palet karena arsitektur token sudah siap. --- ## 6. Architecture ### 6.1 High-Level Architecture ```mermaid graph TD subgraph "tia Binary" A[main.go] --> C[Bubble Tea Program] subgraph "UI Layer" C --> D[Root Model] D --> D1[Sidebar Panel] D --> D2[Content Panel] D --> D3[Status Bar] D --> D4[Modal Stack] end subgraph "Service Layer" E[Docker Service] --> E1[Container Ops] E --> E2[Image Ops] E --> E3[Volume Ops] E --> E4[Network Ops] E --> E5[Stats Collector] E --> E6[Events Listener] F[Stack Service] --> F1[Stack Manager] F --> F2[Stack Scanner] F --> F3[Converter] G[Config Service] --> G1[Setup Wizard] G --> G2[Config Manager] G --> G3[Theme Manager] end subgraph "Docker Layer" H["Docker SDK Client"] --> H1["Container API"] H --> H2["Image API"] H --> H3["System API"] I["docker compose CLI"] --> I1["Compose Ops"] end D --> E D --> F D --> G E --> H F --> I end subgraph "External" J[Docker Daemon] K[Docker Hub Registry] L["Remote Host (SSH)"] end H --> J I --> J E2 --> K L --> J ``` ### 6.2 Project Structure ``` tia/ β”œβ”€β”€ cmd/ β”‚ └── tia-love/ β”‚ └── main.go # Entry point (Router TUI default vs CLI companion) β”œβ”€β”€ internal/ β”‚ β”œβ”€β”€ app/ β”‚ β”‚ β”œβ”€β”€ app.go # Root bubbletea Model β”‚ β”‚ β”œβ”€β”€ keymap.go # Global keybindings β”‚ β”‚ └── messages.go # Custom tea.Msg types β”‚ β”œβ”€β”€ cli/ # Mode CLI pendamping (single binary) β”‚ β”‚ β”œβ”€β”€ root.go # CLI argument parser & dispatcher β”‚ β”‚ β”œβ”€β”€ convert.go # 'tia-love convert' command β”‚ β”‚ β”œβ”€β”€ ps.go # 'tia-love ps' list stacks & containers β”‚ β”‚ β”œβ”€β”€ stack.go # 'tia-love up / down / update' commands β”‚ β”‚ └── doctor.go # 'tia-love doctor' diagnostic check β”‚ β”œβ”€β”€ audio/ # Audio feedback engine (Pure Go, Oto v3) β”‚ β”‚ β”œβ”€β”€ player.go # Audio context & sound player β”‚ β”‚ β”œβ”€β”€ sounds.go # Sound event definitions & mapping β”‚ β”‚ └── assets/ # Embedded CC0 WAV sound files (<2MB) β”‚ β”‚ β”œβ”€β”€ click.wav β”‚ β”‚ β”œβ”€β”€ modal_open.wav β”‚ β”‚ β”œβ”€β”€ modal_close.wav β”‚ β”‚ β”œβ”€β”€ success.wav β”‚ β”‚ β”œβ”€β”€ warning.wav β”‚ β”‚ └── error.wav β”‚ β”œβ”€β”€ ui/ β”‚ β”‚ β”œβ”€β”€ animation/ # ASCII animation & spring physics β”‚ β”‚ β”‚ β”œβ”€β”€ ticker.go # 30 FPS render loop controller β”‚ β”‚ β”‚ β”œβ”€β”€ clock.go # Real-time ASCII digital clock generator β”‚ β”‚ β”‚ └── logo.go # Shimmer / typing ASCII logo banner β”‚ β”‚ β”œβ”€β”€ layout/ β”‚ β”‚ β”‚ β”œβ”€β”€ layout.go # Multi-panel layout manager β”‚ β”‚ β”‚ β”œβ”€β”€ sidebar.go # Left sidebar panel β”‚ β”‚ β”‚ └── content.go # Right content panel β”‚ β”‚ β”œβ”€β”€ views/ β”‚ β”‚ β”‚ └── home.go # Home Dashboard (logo, jam ASCII, metrik, aktivitas) β”‚ β”‚ β”œβ”€β”€ components/ β”‚ β”‚ β”‚ β”œβ”€β”€ toast.go # Top-Center floating notification popup β”‚ β”‚ β”‚ β”œβ”€β”€ statusbar.go # Bottom status/help bar β”‚ β”‚ β”‚ β”œβ”€β”€ tabbar.go # Tab navigation β”‚ β”‚ β”‚ β”œβ”€β”€ logview.go # Real-time log viewer β”‚ β”‚ β”‚ β”œβ”€β”€ statsview.go # CPU/Memory stats with graphs β”‚ β”‚ β”‚ β”œβ”€β”€ inspector.go # JSON inspector β”‚ β”‚ β”‚ β”œβ”€β”€ processview.go # Container processes (top) β”‚ β”‚ β”‚ β”œβ”€β”€ envview.go # Environment variables β”‚ β”‚ β”‚ β”œβ”€β”€ yamlview.go # YAML editor/viewer β”‚ β”‚ β”‚ β”œβ”€β”€ converter.go # docker run β†’ compose UI β”‚ β”‚ β”‚ β”œβ”€β”€ healthview.go # Health check monitor β”‚ β”‚ β”‚ └── registry.go # Registry browser β”‚ β”‚ β”œβ”€β”€ modal/ β”‚ β”‚ β”‚ β”œβ”€β”€ modal.go # Modal dialog base β”‚ β”‚ β”‚ β”œβ”€β”€ confirm.go # Confirmation dialog β”‚ β”‚ β”‚ β”œβ”€β”€ input.go # Text input dialog β”‚ β”‚ β”‚ β”œβ”€β”€ form.go # Multi-field form (huh) β”‚ β”‚ β”‚ β”œβ”€β”€ prune.go # Prune dialog β”‚ β”‚ β”‚ └── resources.go # Resource limits editor β”‚ β”‚ └── theme/ β”‚ β”‚ β”œβ”€β”€ theme.go # Theme manager & token semantik (bg, fg, accent, success, ...) β”‚ β”‚ β”œβ”€β”€ catppuccin.go # Palet Catppuccin: Mocha (gelap) & Latte (terang) β”‚ β”‚ β”œβ”€β”€ detect.go # Deteksi background terminal (gelap/terang) β”‚ β”‚ └── ansi.go # Mode "terminal": pakai palet ANSI terminal pengguna β”‚ β”œβ”€β”€ docker/ β”‚ β”‚ β”œβ”€β”€ client.go # Docker SDK client wrapper β”‚ β”‚ β”œβ”€β”€ container.go # Container CRUD + lifecycle β”‚ β”‚ β”œβ”€β”€ image.go # Image operations β”‚ β”‚ β”œβ”€β”€ volume.go # Volume operations β”‚ β”‚ β”œβ”€β”€ network.go # Network operations β”‚ β”‚ β”œβ”€β”€ compose.go # docker compose CLI wrapper β”‚ β”‚ β”œβ”€β”€ stats.go # Stats streaming β”‚ β”‚ β”œβ”€β”€ events.go # Events listener β”‚ β”‚ β”œβ”€β”€ exec.go # Container exec β”‚ β”‚ β”œβ”€β”€ prune.go # System/resource prune β”‚ β”‚ β”œβ”€β”€ backup.go # Volume backup/restore β”‚ β”‚ └── registry.go # Docker Hub API client β”‚ β”œβ”€β”€ stack/ β”‚ β”‚ β”œβ”€β”€ manager.go # Stack CRUD β”‚ β”‚ β”œβ”€β”€ scanner.go # Filesystem scanner β”‚ β”‚ β”œβ”€β”€ converter.go # docker run β†’ compose parser β”‚ β”‚ β”œβ”€β”€ export.go # Stack export/import β”‚ β”‚ └── types.go # Stack data types β”‚ β”œβ”€β”€ i18n/ β”‚ β”‚ β”œβ”€β”€ i18n.go # Loader & fungsi terjemahan T("key") β”‚ β”‚ └── locales/ β”‚ β”‚ β”œβ”€β”€ id.yaml # Katalog Bahasa Indonesia (default) β”‚ β”‚ └── en.yaml # Katalog English (fallback) β”‚ β”œβ”€β”€ config/ β”‚ β”‚ β”œβ”€β”€ config.go # Config load/save β”‚ β”‚ β”œβ”€β”€ setup.go # First-run setup wizard β”‚ β”‚ β”œβ”€β”€ hosts.go # Multi-host config β”‚ β”‚ └── types.go # Config structs β”‚ └── host/ β”‚ β”œβ”€β”€ manager.go # Multi-host manager β”‚ β”œβ”€β”€ ssh.go # SSH tunnel β”‚ └── types.go # Host types β”œβ”€β”€ install.sh # One-line installer script β”œβ”€β”€ docs/ β”‚ β”œβ”€β”€ PRD.md # This document β”‚ β”œβ”€β”€ ASSETS.md # Open-source assets register β”‚ └── rea/ # Reverse Engineering & Analysis reports β”œβ”€β”€ go.mod β”œβ”€β”€ go.sum β”œβ”€β”€ Makefile β”œβ”€β”€ README.md β”œβ”€β”€ LICENSE └── .goreleaser.yml # Release automation ``` ### 6.3 Key Design Patterns #### Elm Architecture (The Elm Architecture / TEA) ```go // Setiap komponen implement tea.Model type Model interface { Init() tea.Cmd Update(tea.Msg) (tea.Model, tea.Cmd) View() string } ``` #### Message-Driven Communication ```go // Contoh message types type ContainerListMsg []docker.Container type ContainerStatsMsg docker.Stats type LogLineMsg string type DockerEventMsg docker.Event type StackStatusMsg stack.Status type ErrorMsg error ``` #### Composable Components ``` Root Model β”œβ”€β”€ Sidebar Model (bubbles/list) β”‚ β”œβ”€β”€ Stacks List β”‚ β”œβ”€β”€ Containers List β”‚ β”œβ”€β”€ Images List β”‚ β”œβ”€β”€ Volumes List β”‚ └── Networks List β”œβ”€β”€ Content Model β”‚ β”œβ”€β”€ TabBar Model β”‚ β”œβ”€β”€ LogView Model (bubbles/viewport) β”‚ β”œβ”€β”€ StatsView Model β”‚ β”œβ”€β”€ Inspector Model (bubbles/viewport) β”‚ └── ProcessView Model (bubbles/table) β”œβ”€β”€ StatusBar Model (bubbles/help) └── Modal Stack β”œβ”€β”€ Confirm Model β”œβ”€β”€ Form Model (huh) └── Converter Model ``` --- ## 7. Configuration ### 7.1 Config File Location ``` ~/.config/tia/config.yaml ``` ### 7.2 Config Schema ```yaml # tia configuration version: 1 # Stacks directory β€” all managed compose stacks live here stacks_dir: ~/.tia/stacks # UI preferences ui: language: id # id (Indonesia) | en (English); default: id, fallback: en theme: catppuccin # satu-satunya tema bawaan (v1) theme_mode: auto # auto | dark | light | terminal # auto = deteksi background terminal -> Mocha (gelap) / Latte (terang) # dark = Catppuccin Mocha # light = Catppuccin Latte # terminal = pakai palet ANSI terminal pengguna (ikut tema terminal) theme_accent: mauve # warna aksen: rosewater|flamingo|pink|mauve|red|maroon|peach|yellow|green|teal|sky|sapphire|blue|lavender sidebar_width: 0.33 # sidebar width ratio (0.2 - 0.5) show_timestamps: true # show timestamps in logs log_tail_lines: 300 # default number of log lines to tail stats_interval: 1s # stats refresh interval mouse_enabled: true # enable mouse support (click, scroll, drag, hover) mouse_hover: true # hover highlight pada item/tombol/tab mouse_scroll_lines: 3 # jumlah baris per scroll wheel tick double_click_ms: 400 # interval double-click (ms) show_action_buttons: true # tampilkan tombol aksi klikable di toolbar # Audio & Sound Effects sound_enabled: true # aktifkan efek suara (klik, popup notif, alert, modal) sound_volume: 70 # volume suara (0 - 100) sound_mute_on_ssh: true # otomatis senyapkan (mute) suara bila berjalan di sesi SSH # Animasi & Visual Dinamis animation_enabled: true # aktifkan animasi (splash shimmer, pulse indicator, ticker) animation_fps: 30 # frame per second maksimum untuk animasi (default: 30 FPS) # Editor editor: mode: builtin # builtin (editor di dalam tia) | external (suspend TUI, buka editor luar) external_command: "" # kosong = pakai $EDITOR, fallback vim/nano (dipakai hanya jika mode: external) # Docker docker: socket: unix:///var/run/docker.sock compose_command: docker compose # or docker-compose for legacy # Hosts (multi-host) hosts: - name: local type: local default: true # - name: production # type: ssh # address: user@192.168.1.100 # port: 22 # key: ~/.ssh/id_rsa # Keybinding overrides (optional) # keybindings: # quit: q # help: "?" ``` ### 7.3 First-Run Setup Wizard Langkah wizard: **Bahasa β†’ Direktori stack β†’ Tema β†’ Impor stack yang ditemukan.** Bahasa dipilih di langkah pertama (default: Indonesia) dan langsung diterapkan ke langkah berikutnya. ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Selamat datang di tia! Mari kita atur dulu. β”‚ β”‚ β”‚ β”‚ Bahasa / Language: (β€’) Indonesia ( ) English β”‚ β”‚ β”‚ β”‚ Direktori stack: β”‚ β”‚ [ ~/.tia/stacks ] β”‚ β”‚ β”‚ β”‚ Tema: (β€’) Otomatis ( ) Gelap ( ) Terang ( ) Terminal β”‚ β”‚ β”‚ β”‚ Ditemukan 4 stack compose yang ada: β”‚ β”‚ [x] /opt/stacks/nginx β”‚ β”‚ [x] /opt/stacks/postgres β”‚ β”‚ [x] /home/oxpoe/projects/api β”‚ β”‚ [ ] /tmp/test-stack β”‚ β”‚ β”‚ β”‚ Mode impor: (β€’) Salin ( ) Pindah ( ) Symlink β”‚ β”‚ β”‚ β”‚ [ Kembali ] [ Selesai ] β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` --- ## 8. Implementation Roadmap ### Phase 0: Riset, Spike & Fondasi Proses (Week 0-1) > **Goal:** Mengunci keputusan berisiko sebelum membangun UI | Deliverable | Description | |---|---| | **Spike audio** | Buktikan suara bisa diputar dari binary `CGO_ENABLED=0` (Oto v3) di Linux (PulseAudio/PipeWire/ALSA) & macOS; ukur latensi; uji fallback saat tanpa audio device | | **Spike animasi** | Prototipe animasi ASCII 30 FPS + toast slide-in; ukur CPU idle | | REA skill | Buat skill REA + template laporan; jalankan REA modul 1 (composerize) sebagai uji coba alur | | Register aset | `docs/ASSETS.md`, `THIRD_PARTY_NOTICES`; pilih dan unduh aset suara CC0 (Kenney), konversi ke WAV | | Keputusan lisensi | Tetapkan lisensi tia (rekomendasi MIT) | | Repo & CI | Struktur repo, lint, test, goreleaser (dry run) | **Exit Criteria:** Spike audio & animasi lolos target, REA terbukti jalan, aset & lisensi tercatat --- ### Phase 1: Foundation & MVP (Week 1-3) > **Goal:** Working TUI yang bisa browse Docker resources, dengan "rasa" tia (dashboard, animasi, suara, notifikasi) dari awal | Deliverable | Description | |---|---| | Project scaffolding | go mod, project structure, Makefile | | `internal/core` | Lapisan logika bersama (Docker, stack, config) yang **tidak bergantung UI**, dipakai TUI dan CLI | | Root model | Bubble Tea app with 2-panel layout | | **Home Dashboard** | Layar pembuka: logo ASCII beranimasi, jam digital ASCII + tanggal, ringkasan Docker & host, aktivitas terbaru, aksi cepat (F-027) | | Sidebar | Sections: Stacks, Containers, Images, Volumes, Networks | | Content panel | Tab system with placeholder views | | Docker client | SDK connection, list containers/images/volumes/networks | | Navigation | Vim-like keybindings, focus management | | Mouse support | Klik/scroll/hover/klik-kanan, hit-testing zones di layout, toolbar aksi klikable, drag resize sidebar | | **Notifikasi (toast)** | Popup atas-tengah dengan status (sukses/peringatan/gagal/info), antrean, auto-dismiss, klik untuk tutup (F-025) | | **Sound engine** | Efek suara untuk klik, navigasi, modal, notifikasi, sukses, peringatan, error; toggle & volume di Pengaturan (F-024) | | **Animation engine** | Splash logo, shimmer logo, spinner/progress, toast slide-in, transisi status container (F-026) | | i18n (id/en) | Katalog bahasa Indonesia & Inggris, semua string UI lewat katalog (tanpa hardcode), pilih bahasa di wizard & config | | Config | Basic config load/save | | Theme | Catppuccin (Mocha/Latte), mode Otomatis/Gelap/Terang/Terminal, deteksi background terminal, semua warna via token semantik | | Status bar | Context-aware help text (hint klikable) | | **Rilis awal** | goreleaser + Gitea Releases + `install.sh` + checksum (F-029), `tia-love --version` / `tia-love doctor` | **Exit Criteria:** Jalankan `tia-love` β†’ splash β†’ Home Dashboard (jam, ringkasan) β†’ masuk workspace, lihat semua resource Docker, navigasi dengan keyboard **dan mouse**; setiap aksi memberi suara + toast; instal dengan satu baris perintah berhasil di mesin bersih --- ### Phase 2: Monitoring & Logs (Week 3) > **Goal:** Real-time monitoring capabilities | Deliverable | Description | |---|---| | Log viewer | Real-time log streaming, ANSI colors, search, scroll | | Stats view | CPU/Memory/Network/IO graphs, 1s refresh | | Process view | Container processes (docker top) | | Inspector | JSON inspect for any resource | | Env view | Environment variables display | | Events listener | Auto-update resource lists on Docker events | **Exit Criteria:** Select container β†’ see live logs, stats updating, processes --- ### Phase 3: Stack Management & Converter (Week 4-5) > **Goal:** Full stack lifecycle + docker run converter | Deliverable | Description | |---|---| | Stack scanner | Scan & discover existing compose stacks | | Stack manager | Create, start, stop, restart, down, delete, update | | Converter | docker run β†’ compose.yaml with 25+ flags | | Converter UI | Modal: paste β†’ preview β†’ edit β†’ save | | YAML viewer | Syntax highlighted compose.yaml view | | Setup wizard | First-run setup with huh forms | | Compose CLI wrapper | docker compose up/down/pull/restart/ps | | REA modul 1, 2, 7 | Analisis composerize, Dockge (stack), dan format output Compose, hasil di `docs/rea/` + test vectors | | CLI mode (pendamping) | `tia-love convert`, `tia-love ps`, `tia-love stacks`, `tia-love up/down/restart/update`, `--json`, kode keluar jelas (F-028) | **Exit Criteria:** Convert docker run command β†’ save as stack β†’ manage it, **baik dari TUI maupun dari CLI**, dengan hasil identik --- ### Phase 4: Container Actions & Exec (Week 5-6) > **Goal:** Full container lifecycle + exec shell | Deliverable | Description | |---|---| | Container exec | Shell into container (tea.ExecProcess) | | Lifecycle actions | Start, stop, restart, pause, unpause, remove, rename | | Bulk actions | Multi-select + batch operations | | Context menu | Action menu (`x`) for all available actions | | Confirm dialogs | Confirmation for destructive actions | **Exit Criteria:** Exec into container, bulk stop/remove, all lifecycle actions work --- ### Phase 5: Advanced Features (Week 7-8) > **Goal:** Power-user features | Deliverable | Description | |---|---| | System prune | Interactive cleanup with space preview | | Health check monitor | Health status tracking & history | | Resource limits editor | Modify CPU/memory limits on running containers | | Dockerfile builder | Basic editor + build integration | | Registry browser | Search Docker Hub, view tags, pull | | Stack export/import | Pack/unpack stacks as .tar.gz | | Volume backup | Backup/restore named volumes | **Exit Criteria:** All advanced features functional --- ### Phase 6: Multi-Host (Week 9-10) > **Goal:** Manage Docker on remote servers | Deliverable | Description | |---|---| | Host manager | Add/remove/edit remote hosts | | SSH tunnel | Forward remote Docker socket | | Host selector | Switch between hosts in sidebar | | Remote operations | All features work on remote hosts | **Exit Criteria:** Add remote host β†’ manage its containers/stacks from tia --- ## 9. Non-Functional Requirements ### Performance - Startup time < 500ms - UI response < 16ms (60fps) - Memory usage < 50MB idle, < 100MB active monitoring - Efficient rendering via Cursed Renderer (cell-diffing) - Animasi dibatasi **30 FPS**, CPU idle < 3% saat dashboard terbuka - Inisialisasi audio **tidak memblok startup** (dilakukan di background); suara pertama < 100 ms setelah siap - Ukuran binary: target < 25 MB (termasuk aset suara < 2 MB) ### Compatibility - Linux (primary) - macOS (secondary) - Windows (WSL2 β€” best effort) - Docker Engine 20.10+ - Docker Compose v2 (plugin mode) ### Input & Mouse Support - **Mouse-first friendly:** semua fitur utama dapat dioperasikan penuh dengan mouse, keyboard tetap first-class (tidak ada fitur mouse-only atau keyboard-only) - Mouse capture aktif by default (`mouse_enabled: true`), bisa dimatikan via config - Tampilan harus mengindikasikan elemen yang bisa diklik (hover highlight, tombol berlabel, kursor/affordance jelas) - Kompatibel dengan terminal modern (kitty, alacritty, wezterm, gnome-terminal, iTerm2), tmux, dan SSH session - Fallback graceful bila terminal tidak mendukung mouse ### Distribution - **Satu binary statis** (`CGO_ENABLED=0`), tanpa runtime dependency selain Docker (audio memakai library pure-Go; server audio hanya dibutuhkan jika suara diaktifkan) - Instal satu baris (skrip) **atau** unduh binary manual dari Gitea Releases, detail di **F-029** - Release otomatis via goreleaser: `.tar.gz`/`.zip` + `checksums.txt`; `.deb`, `.rpm`, Homebrew, AUR menyusul - Binary name: `tia-love` (nama produk tetap: tia) ### Audio & Animasi - Suara dan animasi **opsional**: bisa dimatikan penuh dari Pengaturan, dan aplikasi tetap 100% fungsional tanpa keduanya - Setiap suara dan animasi punya padanan visual/teks agar informasi tidak hanya lewat bunyi - Mode "reduced motion" untuk pengguna yang sensitif terhadap gerakan ### Security - No credentials stored in plaintext (SSH keys referenced by path) - Docker socket access follows system permissions - Confirmation for all destructive operations --- ## 10. Success Metrics | Metric | Target | |---|---| | Docker run β†’ compose conversion accuracy | > 95% untuk common flags | | TUI startup time | < 500ms | | Real-time stats latency | < 2 seconds | | Container exec suspend/resume | Clean, no artifacts | | Stack operations (up/down/restart) | Same reliability as native CLI | | Multi-host connection | < 5 seconds SSH tunnel setup | | Mouse coverage | 100% aksi utama bisa dilakukan hanya dengan mouse (tanpa keyboard) | | Parity keyboard & mouse | Setiap fitur bisa lewat keyboard DAN mouse | | Latensi suara klik | < 100 ms dari aksi sampai terdengar | | Notifikasi (toast) muncul | < 100 ms setelah event, tampil di atas-tengah dengan status lengkap | | Animasi | Stabil 30 FPS, CPU idle < 3% saat dashboard terbuka | | Instalasi satu baris | < 30 detik dari perintah sampai `tia-love` bisa dijalankan | | Paritas CLI vs TUI | Hasil konversi & operasi stack lewat CLI identik dengan lewat TUI | | Coverage aset | 100% aset tercatat di register aset dengan lisensi valid | --- ## 11. Risks & Mitigations | Risk | Impact | Mitigation | |---|---|---| | Charm v2 breaking changes (baru release) | High | Pin exact versions, thorough testing | | Docker API version incompatibility | Medium | Use API version negotiation | | Terminal compatibility (colors, unicode) | Medium | Lipgloss adaptive colors, fallback ASCII | | Complex compose files break converter | Medium | Focus on common flags, graceful fallback | | SSH tunnel instability | Low | Reconnection logic, timeout handling | | Mouse event tidak konsisten antar terminal/tmux/SSH | Medium | Test di terminal populer (kitty, alacritty, wezterm, gnome-terminal, tmux, SSH), keyboard selalu jadi fallback penuh, toggle mouse via config | | Mouse capture mengganggu copy-paste teks native | Medium | Sediakan mode "text select" (toggle `m`) + tombol Copy di log/YAML viewer + dukungan OSC52 clipboard | | Suara tidak terdengar saat tia dijalankan lewat SSH (audio diputar di server, bukan di laptop pengguna) | High | Deteksi sesi SSH β†’ suara default mati + info; semua suara selalu punya padanan visual; opsi terminal bell (BEL) sebagai fallback; rekomendasikan pola "tia lokal + multi-host" | | Tidak ada audio device/server (PulseAudio/PipeWire/ALSA) di mesin | Medium | Deteksi saat start, degradasi diam-diam ke mode tanpa suara + notifikasi sekali; `tia-love doctor` menampilkan status audio | | Dependensi audio merusak single static binary (cgo) | High | Pilih library audio pure-Go (Oto v3 dengan `CGO_ENABLED=0`); **spike teknis di Phase 0** untuk membuktikan sebelum dikunci | | Animasi menghabiskan CPU / flicker di terminal lambat | Medium | Batas 30 FPS, animasi dimatikan otomatis saat idle/terminal lambat, mode "reduced motion", toggle di Pengaturan | | Spam suara/notifikasi dari event Docker beruntun | Medium | Debounce, rate limit, dan pengelompokan notifikasi sejenis | | Pola `curl \| sh` dianggap tidak aman | Medium | HTTPS saja, verifikasi checksum SHA256, skrip ringkas bisa dibaca, instal ke `~/.local/bin` tanpa sudo, sediakan jalur instal manual | | Pelanggaran lisensi aset / kode referensi | High | Kebijakan aset open source (Appendix C), register aset, aturan REA "tulis ulang, jangan salin", verifikasi lisensi di awal tiap modul | | Pertentangan prinsip TUI-first dengan mode CLI | Low | CLI hanya pendamping non-interaktif; seluruh logika di `internal/core` dipakai bersama sehingga tidak ada duplikasi | --- ## 12. REA Skill: Reverse Engineering & Analysis > [!NOTE] > Singkatan "REA" saya artikan sebagai **Reverse Engineering & Analysis**. Bagian ini perlu dikonfirmasi (lihat Open Questions). ### 12.1 Tujuan REA adalah **skill kerja** (panduan terstruktur untuk agent/developer) yang dipakai selama pengembangan untuk **menganalisis logika backend proyek referensi** (Dockge, lazydocker, composerize) lalu **mem-porting perilakunya ke Go** di dalam tia, dengan hasil yang bisa diverifikasi. Yang dianalisis dan di-clone adalah **logika backend** (alur, algoritma, aturan, format data, perintah Docker). **Bukan** UI, branding, aset, atau frontend mereka. ### 12.2 Aturan Legal & Etika 1. **Cek lisensi dulu** langsung dari repo sumber sebelum menyentuh kodenya (target saat ini umumnya MIT, tapi wajib diverifikasi) 2. **Tulis ulang, jangan salin.** Pelajari perilaku dan algoritma, lalu implementasikan sendiri dalam Go. Tidak ada copy-paste kode verbatim 3. Jika ada bagian yang terpaksa diadaptasi dekat dengan aslinya, **cantumkan atribusi** dan lisensi aslinya di `THIRD_PARTY_NOTICES` 4. Jangan pernah menganalisis/meniru proyek **closed-source** atau berlisensi tidak jelas 5. Jangan mengambil nama, logo, atau aset visual proyek referensi ### 12.3 Bentuk Skill - Disimpan di repo sebagai skill (`SKILL.md` + template laporan), lokasi final mengikuti konvensi skill Antigravity - Dipanggil per modul: "REA: analisis `` dari ``" - Output selalu berupa dokumen analisis + test vectors + spesifikasi port, sebelum satu baris kode Go ditulis ### 12.4 Alur Kerja ```mermaid flowchart LR A[1. Scope] --> B[2. Map] B --> C[3. Trace] C --> D[4. Spec] D --> E[5. Port] E --> F[6. Verify] F -->|beda perilaku| C ``` | Langkah | Aktivitas | Output | |---|---|---| | 1. **Scope** | Tentukan modul & batasnya, cek lisensi | Catatan scope + lisensi | | 2. **Map** | Petakan file/fungsi/struktur data yang relevan | Peta modul | | 3. **Trace** | Telusuri alur eksekusi dari input ke output, termasuk edge case & error path | Diagram alur + daftar edge case | | 4. **Spec** | Tulis spesifikasi netral: input, output, aturan, tabel pemetaan, perintah Docker yang dipanggil | `docs/rea/.md` + test vectors | | 5. **Port** | Implementasi ulang dalam Go (terpisah dari UI, di `internal/core`) | Kode Go + unit test | | 6. **Verify** | Uji paritas: input sama harus menghasilkan output setara dengan referensi | Laporan paritas (lolos/gagal per kasus) | ### 12.5 Template Laporan Analisis (`docs/rea/.md`) - Ringkasan & tujuan modul - Sumber (repo, commit/versi, lisensi) - Alur eksekusi (diagram) - Struktur data & format I/O - Aturan & edge case - Perintah Docker/Compose yang dipanggil beserta format outputnya - Test vectors (input β†’ output yang diharapkan) - Perbedaan yang disengaja dari referensi (dan alasannya) ### 12.6 Target Analisis | # | Modul referensi | Yang dianalisis | Hasil di tia | Fase | |---|---|---|---|---| | 1 | **composerize** | Parser flag `docker run`, tokenisasi (quote, backslash, multi-line), pemetaan flag β†’ field compose, normalisasi | `internal/stack/converter.go` + korpus test | 3 | | 2 | **Dockge** (stack) | Scan folder stack, kandidat nama file compose (`compose.yaml`, `compose.yml`, `docker-compose.yaml`, `docker-compose.yml`), normalisasi nama project, rekonsiliasi status (`docker compose ls --all --format json` vs isi disk), deteksi unmanaged, pola perintah up/down/pull/restart | `internal/stack/scanner.go`, `manager.go`, `internal/docker/compose.go` | 3 | | 3 | **Dockge** (agent) | Arsitektur primary ↔ agent untuk multi-host (ide desain; tia memakai SSH tunnel) | `internal/host/*` | 6 | | 4 | **lazydocker** (commands) | Pemanggilan Docker SDK: list/inspect, stats streaming, buffer riwayat CPU/RAM, deteksi shell, log streaming | `internal/docker/*` | 2, 4 | | 5 | **lazydocker** (tasks) | Manajemen stream di background: cancel stream saat pilihan pindah, cegah goroutine bocor | Pola stream/cancel pada TUI | 2 | | 6 | **lazydocker** (custom commands) | Template perintah kustom dengan placeholder | Fitur custom commands (opsional) | 5 | | 7 | **Docker/Compose CLI** | Format JSON `compose ls`, `compose ps`, `compose config`, kode keluar | Parser output compose | 3 | ### 12.7 Verifikasi Paritas - **Golden tests:** pasangan input/output dari analisis disimpan sebagai test vectors - **Differential testing (converter):** jalankan korpus perintah `docker run` yang sama pada composerize dan converter tia, lalu bandingkan YAML hasilnya setelah dinormalisasi (urutan key, kutip) - **Target paritas:** β‰₯ 95% pada flag umum (selaras dengan success metric converter); setiap perbedaan harus tercatat sebagai "perbedaan yang disengaja" - **Integration test** dengan Docker sungguhan untuk scanner dan status stack ### 12.8 Definition of Done per Modul - [ ] Lisensi sumber sudah diverifikasi dan dicatat - [ ] Laporan analisis `docs/rea/.md` selesai - [ ] Test vectors tersedia - [ ] Implementasi Go terpisah dari UI (bisa dipakai TUI **dan** CLI) - [ ] Uji paritas lolos sesuai target - [ ] `THIRD_PARTY_NOTICES` diperbarui bila perlu --- ## 13. Future Considerations (Post v1.0) - [ ] Docker Swarm support - [ ] Kubernetes basic support (pods, deployments) - [ ] Plugin system (custom commands via Go plugins or Lua) - [ ] Remote access via SSH TUI (using Charm's `wish`) - [ ] Notification integrations (Discord, Telegram, Slack) - [ ] Container metrics history & persistence - [ ] Compose file templates marketplace - [ ] AI-assisted compose generation - [ ] Container security scanning integration (Trivy, Grype) --- ## Appendix A: Reference Projects | Project | URL | What We Take | |---|---|---| | Dockge | https://github.com/louislam/dockge | Stack management, converter, file-system approach | | lazydocker | https://github.com/jesseduffield/lazydocker | UI layout, keybindings, multi-panel design | | Charm (bubbletea) | https://github.com/charmbracelet/bubbletea | TUI framework | | Charm (bubbles) | https://github.com/charmbracelet/bubbles | UI components | | Charm (lipgloss) | https://github.com/charmbracelet/lipgloss | Styling | | Charm (huh) | https://github.com/charmbracelet/huh | Forms | | Mirador | https://github.com/jchultarsky/mirador | Inspirasi tata letak dashboard TUI (panel grid dengan judul di border, meta kanan, jam blok, satu panel fokus terang) | ## Appendix B: Charm v2 Import Paths ```go import ( tea "charm.land/bubbletea/v2" "charm.land/bubbles/v2/list" "charm.land/bubbles/v2/table" "charm.land/bubbles/v2/viewport" "charm.land/bubbles/v2/textinput" "charm.land/bubbles/v2/help" "charm.land/bubbles/v2/key" "charm.land/bubbles/v2/spinner" "charm.land/bubbles/v2/progress" "charm.land/lipgloss/v2" "charm.land/huh/v2" "charm.land/glamour/v2" "charm.land/log/v2" ) ``` ## Appendix C: Aset Open Source & Lisensi ### Kebijakan - Semua aset (suara, palet, font, ikon, library) **wajib open source / bebas dipakai**: CC0, MIT, Apache-2.0, BSD, OFL - **Dilarang:** lisensi NC (non-commercial), ND (no-derivatives), atau lisensi yang tidak jelas - Setiap aset dicatat di **register aset** (`docs/ASSETS.md` + `THIRD_PARTY_NOTICES`): nama, penulis, URL sumber, lisensi, tanggal diambil, dan file mana yang memakainya - Aset suara di-embed ke binary, jadi atribusi harus ikut tersedia dari dalam aplikasi (menu **Tentang**) - Lisensi tia sendiri perlu diputuskan (rekomendasi: **MIT**); lihat Open Questions ### Sumber yang direkomendasikan | Kebutuhan | Sumber | Lisensi | Catatan | |---|---|---|---| | Efek suara UI (klik, notif, alert) | **Kenney: Interface Sounds / UI Audio** (kenney.nl) | CC0 | Pilihan utama, tanpa kewajiban atribusi | | Efek suara tambahan | OpenGameArt (filter **CC0** saja) | CC0 | Cek lisensi per file | | Efek suara tambahan | Freesound (filter **CC0** saja) | CC0 | Hindari CC-BY-NC | | Palet warna | **Catppuccin** | MIT | Sudah diputuskan | | Logo ASCII & animasi | **Buatan sendiri** | Ikut lisensi tia | Menghindari masalah lisensi font | | Font ASCII (jika dipakai) | FIGlet / font lain | **Beda per font** | Wajib cek lisensi tiap font sebelum dipakai | | Glyph/ikon | Unicode standar (●, β—‹, β–Ά, ⟳, βœ”, ⚠) | Bebas | **Tidak mewajibkan Nerd Font**; sediakan fallback ASCII | | Library TUI | Charm (bubbletea, bubbles, lipgloss, huh, glamour, log, harmonica) | MIT | | | Library Docker | Docker SDK for Go | Apache-2.0 | | | Library audio | Oto (ebitengine) | Apache-2.0 | | ### Format aset suara - Sumber asli biasanya OGG. Untuk menghindari dependensi decoder tambahan, **konversi ke WAV** (44.1 kHz, 16-bit, mono) saat build aset - Efek suara berdurasi pendek (< 1 detik), target total aset suara **< 2 MB** di dalam binary - File suara disimpan di `internal/audio/assets/` dan di-embed lewat `go:embed` > [!NOTE] > Lisensi proyek referensi (Dockge, lazydocker, composerize) umumnya MIT, tetapi **wajib diverifikasi ulang langsung dari repo masing-masing** sebelum ada logika yang diadaptasi. Lihat bagian REA Skill.