Back to ezstack

Desktop
App

A native desktop GUI for ezstack, built with Tauri. See your stacks as a visual graph, run every operation through dialogs, and even drive an ezs install on a remote machine over SSH — all without touching the terminal.

$ cd tauri-ui && npm install && npm run tauri build
Download from Releases
Three-Panel Layout

Your stacks at a glance

The desktop app uses a three-panel layout: stacks sidebar on the left, the visual stack graph in the middle, and a detail view on the right for the selected branch.

1

Visual stack graph

The middle panel renders your stacks as a tree of branches, color-coded by health and with the current branch highlighted. Click any node to see PR state, CI checks, review status, and mergeable state in the detail panel.

# What you see in the desktop window:
┌──────────┬──────────────────────┬───────────────────┐
│ Stacks   │   main (base)        │  feat/auth
│          │    └─ feat/auth      │  PR: #42 [OPEN]   
│ ● myapp  │        └─ feat/login │  CI: 3/3 passed  ✓
│   2 br   │                      │  Review: Approved
│          │                      │  [Sync] [Push]    │
└──────────┴──────────────────────┴───────────────────┘
2

Live status, polled every 30s

The app polls ezs status in the background and refreshes after every operation. Polling pauses when the window loses focus and uses exponential backoff on failures so it never gets in your way.

# Title bar shows live connection health:
 Connected   # green: latency ≤ 800 ms
 Slow        # yellow: latency > 800 ms
 Error       # red: last ping failed (hover for details)

# Backoff schedule on failure:
30s → 60s → 120s → 240s → 300s
3

Repo picker, filter & theme

Every repo tracked in ~/.ezstack/config.json shows up in the left sidebar. Type in the Filter box to narrow the list by name or full path — useful when a single config tracks dozens of repos. The currently selected repo stays visible even if it doesn't match the filter, so the main panel can never show a repo you can't click back to. Toggle dark, light, or system theme from the title bar.

# Keyboard shortcuts:
Cmd+R    # refresh
Cmd+N    # new branch
Esc      # clear selection / clear sidebar filter
↑ / ↓    # move between branches in the selected stack
← / →    # move between stacks (also [ and ])
4

Reflog history & drag-to-reparent

The branch detail panel shows a History timeline with the most recent reflog entries for the selected branch — short hash, action (checkout, rebase, commit…), and the full message — so you can spot a bad rebase or an unexpected reset without dropping to a terminal. Over in the stack graph, branch nodes are drag-and-drop reparentable: drag a node onto another branch and the app runs ezs reparent with the configured sync strategy. Drops that would form a cycle (onto a descendant), drops onto the branch itself, and drops onto the current parent are blocked with an inline toast so you can't accidentally corrupt the stack graph.

# Branch detail → History:
abc1234  HEAD@{0}  checkout: moving from main to feat/b
def5678  HEAD@{1}  rebase (start): checkout origin/main
9ab0011  HEAD@{2}  commit: wire up the cycle check

# Drag-to-reparent (valid vs. blocked):
feat/b  →  feat/x          # ok: same stack, new parent
feat/a  →  feat/c          # blocked: would create a cycle
feat/b  →  feat/b          # blocked: dropped on self
Operations

Every CLI operation, as a dialog

The Rust backend is a thin wrapper around the ezs CLI. The frontend exposes every operation through typed forms with confirmation dialogs — and shows the raw CLI output in a terminal-like panel below.

1

Branch operations

Create, sync, push, delete, and reparent branches without ever touching a terminal.

New branch      # pick parent from a dropdown
Sync            # current branch, stack, or all stacks
Push            # current branch or full stack
Delete          # with force toggle
Reparent        # pick a new parent branch
2

Pull request operations

Create, update, merge, and toggle draft for PRs. Refresh the stack navigation table in every PR description in one click.

PR Create       # title, description, draft toggle
PR Update       # push and refresh
PR Merge        # squash, merge, or rebase
Toggle Draft    # draft ↔ ready
Update Stack    # refresh PR descriptions in the stack
3

AI agent integration

Launch the ezstack agent on the current branch or stack, build a feature from a description, and edit prompts across all three layers (shipped, custom, repo) directly from the GUI.

Agent           # branch- or stack-scoped
Agent Feature   # describe the feature, get stacked PRs
Agent Prompts   # view / edit / reset across all 3 layers
4

Toast notifications

Every mutation surfaces a toast in the bottom-right corner with a labelled title (Push feat/auth succeeded, Reparent feat/b onto main failed) and the first line of CLI output. Success toasts auto-dismiss after five seconds; error toasts stay until you dismiss them so you can copy the failure message. Toasts expose the right ARIA live-region roles so screen readers announce them, and the list is capped so a burst of operations can't flood the screen.

✓ Sync stack succeeded
  Rebased 3 branches onto main.

✗ Reparent feat/b onto feat/c failed
  error: would create a cycle
Remote (SSH) Mode

Drive ezstack on a remote machine

The desktop app can become a thin client for an ezs install on a remote host. Every ezs, git, and gh invocation runs on the remote — useful for repos that live on a dev VM, build server, or beefy workstation.

1

Connect with saved profiles

Click the Connect pill in the title bar, fill in host / user / port / key, and optionally a jump host (passed through as ssh -J). Profiles are saved to ~/.ezstack/desktop/connections.json — no secrets stored, auth runs through your SSH agent or key file.

Host:        dev-box.internal
User:        kk
Port:        22
Key:         ~/.ssh/id_ed25519
Jump host:   bastion.internal     # optional
Label:       "dev box"            # optional
2

Diagnose health in 6 steps

The connect dialog has a Diagnose button that runs a six-step probe and reports pass / warn / fail with a per-step duration so you can see exactly where things break.

 SSH connectivity + latency           42ms
 Login shell PATH                     12ms
 ezs binary present and runnable      88ms
 git present                          15ms
 gh authenticated                    160ms
 ~/.ezstack/config.json readable      11ms
3

Live health pings

Once connected, the app pings the remote every 30 seconds. The title-bar pill turns green (healthy), yellow (slow), or red (failed). Hover for the latency or the last error.

# Known limitations:
- Agent prompt EDIT is local-only over SSH (view/reset still work)
- First connect uses StrictHostKeyChecking=accept-new
- Every op is at least one SSH round-trip — expect a beat of latency

Installation

Requires Node.js 18+, the Rust toolchain (for building), and the ezs CLI on $PATH. gh (GitHub CLI) is required for PR features.

From the release page

Grab the prebuilt installer for your platform from the GitHub releases page and run it. The app auto-discovers your repos.

# Download from:
github.com/KulkarniKaustubh/ezstack/releases

# macOS (universal)
$ open ezstack_4.4.2_universal.dmg

# Windows (.msi or .exe installer)
$ msiexec /i ezstack_4.4.2_x64_en-US.msi

# Linux (.AppImage / .deb / .rpm)
$ chmod +x ezstack_4.4.2_amd64.AppImage

From source

Clone the repo, install dependencies, and run the dev build (Vite hot reload + Tauri window) or produce a release bundle.

$ cd tauri-ui
$ npm install

# Dev (hot reload)
$ npm run tauri dev

# Production bundle
$ npm run tauri build
  → src-tauri/target/release/bundle/

Tech stack

Built on a small set of well-known tools.

Layer Technology
Framework Tauri v2
Frontend React 19 + TypeScript 5.7
Styling Tailwind CSS v4
State Zustand 5
Icons Lucide React
Build Vite 6
Backend Rust — thin wrapper around ezs via std::process::Command
Download from Releases