{"id":46457516,"url":"https://github.com/studiowebux/zurm","last_synced_at":"2026-05-16T21:17:51.012Z","repository":{"id":341493315,"uuid":"1170296070","full_name":"studiowebux/zurm","owner":"studiowebux","description":"A GPU-rendered terminal emulator for macOS, written in Go.","archived":false,"fork":false,"pushed_at":"2026-05-16T19:29:02.000Z","size":2745,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-16T19:33:19.568Z","etag":null,"topics":["claude-code","configurable","ebitengine","ffmpeg","file-explorer","golang","gpu-accelerated","llms","macos","markdown","mouse-support","multi-panes","multi-tabs","session","status-bar","terminal","tts-stt","vibe-coded"],"latest_commit_sha":null,"homepage":"https://zurm.dev/","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/studiowebux.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-02T00:51:03.000Z","updated_at":"2026-05-16T19:23:36.000Z","dependencies_parsed_at":"2026-03-11T00:00:41.587Z","dependency_job_id":null,"html_url":"https://github.com/studiowebux/zurm","commit_stats":null,"previous_names":["studiowebux/zurm"],"tags_count":52,"template":false,"template_full_name":null,"purl":"pkg:github/studiowebux/zurm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/studiowebux%2Fzurm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/studiowebux%2Fzurm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/studiowebux%2Fzurm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/studiowebux%2Fzurm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/studiowebux","download_url":"https://codeload.github.com/studiowebux/zurm/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/studiowebux%2Fzurm/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33119128,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-16T18:38:32.183Z","status":"ssl_error","status_checked_at":"2026-05-16T18:38:29.903Z","response_time":115,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["claude-code","configurable","ebitengine","ffmpeg","file-explorer","golang","gpu-accelerated","llms","macos","markdown","mouse-support","multi-panes","multi-tabs","session","status-bar","terminal","tts-stt","vibe-coded"],"created_at":"2026-03-06T02:53:10.105Z","updated_at":"2026-05-16T21:17:50.979Z","avatar_url":"https://github.com/studiowebux.png","language":"Go","funding_links":["https://buymeacoffee.com/studiowebux","https://github.com/sponsors/studiowebux","https://patreon.com/studiowebux"],"categories":[],"sub_categories":[],"readme":"# zurm\n\n\u003e **zurm** /zɜːrm/\n\u003e\n\u003e *noun* — The low, satisfying hum of a terminal session where everything just works. A state of flow achieved when your shell config is finally dialed in.\n\u003e\n\u003e *verb* — To move through command-line tasks with effortless speed. *\"I zurmed through the deploy in under a minute.\"*\n\u003e\n\u003e *origin* — Onomatopoeia. The sound a cursor makes if you really listen. A blend of zoom and whirr, with the grounding weight of firm.\n\n---\n\n*zurm — feel the hum.*\n\n---\n\nA GPU-rendered terminal emulator for macOS, written in Go.\n\n## Why this project exists?\n\nA curiosity project: how far can vibe-coded development go when the target is a tool you actually use every day? zurm is the answer so far — a GPU-rendered terminal built entirely through AI-assisted coding, no prior Ebitengine or terminal emulator experience required. It handles everything I need from a terminal. The experiment is ongoing.\n\nBug tracker: https://github.com/studiowebux/zurm/issues\n\u003cbr\u003e\nDiscord: https://discord.gg/BG5Erm9fNv\n\n## Funding\n\n[Buy Me a Coffee](https://buymeacoffee.com/studiowebux)\n\u003cbr\u003e\n[GitHub Sponsors](https://github.com/sponsors/studiowebux)\n\u003cbr\u003e\n[Patreon](https://patreon.com/studiowebux)\n\n## Features\n\n| Category | Feature | Details |\n|---|---|---|\n| **Rendering** | GPU compositing | Ebitengine offscreen rendering at native resolution |\n| | HiDPI / Retina | Physical-pixel layout with automatic scale factor detection |\n| | Dirty-flag redraw | Only renders when state changes; TPS drops to 1 after 5s unfocused |\n| | Wide characters | CJK characters render with correct double-width columns |\n| | Font fallback chain | Multiple fonts tried in order; covers Latin, CJK, symbols |\n| **Terminal** | xterm-256color | Full 256-color and truecolor (24-bit) support |\n| | ANSI palette | Configurable 16-color palette via TOML |\n| | PTY per pane | Each pane owns its shell, buffer, and cursor independently |\n| | VT parser | Handles CSI, OSC, DCS, alternate screen, scroll regions |\n| | Kitty keyboard | Extended key protocol for unambiguous modifier detection |\n| | Mouse modes | X10 + SGR mouse reporting, focus events |\n| **Panes** | Binary tree splits | Cmd+D horizontal, Cmd+Shift+D vertical, any depth |\n| | Resize drag | Mouse drag on dividers or Cmd+Opt+Arrow (5% step) |\n| | Zoom | Cmd+Z temporarily fullscreens the focused pane |\n| | Detach / move | Detach pane to new tab or move between tabs |\n| | Headers | Name labels with scroll position indicator |\n| | Rename | Double-click header, right-click menu, or command palette |\n| | Persist | Pane names and layout survive session save/restore |\n| **Tabs** | Parking | Cmd+Shift+K — hide tab from bar, keep PTY alive; Cmd+J to find/unpark |\n| | Max open | `[tabs] max_open = 10` caps visible tabs; parked tabs are unlimited |\n| | Switcher | Cmd+Shift+T — fuzzy overlay to switch by name |\n| | Search | Cmd+J — filter all tabs (visible + parked) by name or CWD |\n| | Pins | Cmd+G → home-row key (a–l) for instant tab jump; works with parked tabs |\n| | Notes | Cmd+Shift+N — persistent text note per tab; shown in status bar |\n| | Reorder | Cmd+Shift+←/→ or mouse drag |\n| | Activity indicator | Purple dot on tabs with unseen PTY output; badge glow for parked |\n| | Hover preview | Minimap popover on background tab hover |\n| | Focus history | Cmd+; — stack of 50 previously viewed tabs/panes |\n| **File Explorer** | Tree sidebar | Cmd+E — browse, create, rename, delete, copy path |\n| | Finder reveal | Open file location in macOS Finder |\n| | Search filter | / to filter entries (Telescope-style flat list) |\n| **Selection** | Click / word / line | Click, double-click, triple-click with drag |\n| | Auto-scroll | Selection drag past viewport edges scrolls automatically |\n| | Wide char aware | Selection handles double-width characters correctly |\n| | Cmd+C / Cmd+V | Copy selection, paste with bracketed paste + NFC normalization |\n| **Scrollback** | Ring buffer | Configurable size (default 10,000 lines) |\n| | Search | Cmd+F — incremental search across scrollback + primary screen |\n| | Mouse wheel | Scroll through history; Shift+Wheel overrides PTY mouse mode |\n| **URLs \u0026 Blocks** | Cmd+click URLs | Opens detected URLs in the default browser |\n| | OSC 133 blocks | Command prompt/output tracking via shell hooks |\n| | Block hover copy | Hover a command block to copy its output; elapsed timer shown |\n| **Markdown** | Reader mode | Cmd+Shift+M — renders terminal content as markdown via goldmark |\n| | Search | Cmd+F with match highlighting inside the viewer |\n| | Vim motions | gg, G, Ctrl+d/u, j/k navigation |\n| **llms.txt** | Browser | Cmd+L — fetch and display llms.txt from any domain |\n| | Hint-mode links | Follow links by label, keyboard-driven navigation |\n| | History nav | Back/forward through browsed pages |\n| | Send to pane | Pipe content from llms.txt browser to the focused terminal |\n| **Server (Mode B)** | Session persistence | Optional `zurm-server` daemon manages PTY sessions in the background |\n| | Auto-start | Server spawns on demand when you create a server pane — no manual setup |\n| | Per-pane opt-in | Cmd+Shift+B (tab), Cmd+Shift+H/V (split) — local panes unaffected |\n| | Reattach | Cmd+P → \"Attach to Server Session\" or `zurm -a \u003cid\u003e` (prefix match) |\n| | CLI | `zurm -ls` lists sessions; `zurm -a 7ff` attaches by short ID |\n| | Status indicator | [SERVER] badge in status bar when focused pane is server-backed |\n| **Vault** | Command history | Encrypted local command vault; imports ~/.zsh_history on first run |\n| | Ghost suggestions | Fish-style inline ghost text as you type; right arrow to accept |\n| | Privacy | Space-prefixed commands excluded; AES-256-GCM encryption at rest |\n| **Recording** | Screenshot | Cmd+Shift+S — PNG capture to ~/Pictures/zurm-screenshots/ |\n| | Screen recording | Cmd+Shift+. — FFMPEG MP4 at 30fps to ~/Movies/zurm-recordings/ |\n| | Status indicator | Elapsed time and file size shown in status bar while recording |\n| **Config** | TOML | `~/.config/zurm/config.toml` — auto-generated with defaults on first launch |\n| | Hot-reload | Cmd+, — reload config without restarting |\n| | Theme system | External TOML themes in `~/.config/zurm/themes/` |\n| | Font size adjust | Cmd+= / Cmd+- on the fly |\n| **Session** | Save / restore | Tabs, panes, layout, CWDs, pins, notes — all persisted. `--no-restore` to skip |\n| | Auto-save | Optional automatic session save on quit |\n| **Status Bar** | Live indicators | CWD, git branch, process, scroll offset, zoom, recording, version |\n| **macOS** | .app bundle | ARM64 build via GitHub Actions |\n| | DMG distribution | Drag-to-install disk image |\n| | Gatekeeper | `xattr -d com.apple.quarantine` or right-click → Open |\n| | Left Option as Meta | Configurable; right Option composes macOS characters |\n\n## Installation\n\n### Binary\n\nDownload the latest release from https://github.com/studiowebux/zurm/releases\n\n**`zurm-macos-arm64.dmg`** — .app bundle, drag to `/Applications` and launch normally.\n\n**`zurm`** — raw binary, run directly from the terminal.\n\nThe app is not notarized yet. On first launch macOS Gatekeeper will block it. To allow it:\n\n```bash\n# For the .app bundle\nxattr -d com.apple.quarantine zurm.app\n\n# For the raw binary\nxattr -d com.apple.quarantine zurm\nchmod +x zurm\n```\n\nOr: right-click → Open → Open anyway.\n\n### From source\n\n```bash\ngit clone https://github.com/studiowebux/zurm\ncd zurm\ngo build -o zurm .\n```\n\n## Usage\n\n```bash\n./zurm\n./zurm --no-restore   # skip session restore, open a single fresh tab\n./zurm -ls            # list active zurm-server sessions\n./zurm -a 7ff         # attach to a server session by short ID prefix\n```\n\n## Server Mode (Mode B)\n\nzurm can delegate PTY sessions to a background daemon (`zurm-server`) so they survive GUI restarts. This is opt-in per pane — local panes are never affected.\n\n### Quick start\n\n1. Build: `make build \u0026\u0026 make build-server`\n2. Open zurm and press **Cmd+Shift+B** to create a server-backed tab\n3. zurm-server auto-starts in the background (no manual setup)\n4. Quit zurm, relaunch — the server pane reconnects with output preserved\n\n### Keybindings\n\n| Key | Action |\n|-----|--------|\n| Cmd+Shift+B | New server tab |\n| Cmd+Shift+H | Split horizontal (server pane) |\n| Cmd+Shift+V | Split vertical (server pane) |\n| Cmd+P → \"Attach\" | Attach to an existing server session |\n\n### CLI\n\n```bash\nzurm -ls              # list active sessions (ID, PID, size, dir)\nzurm -a \u003cid\u003e          # attach by full or short ID (Docker-style prefix matching)\n```\n\n### How it works\n\n- `zurm-server` is a headless daemon that owns PTY sessions\n- Each server pane connects over a Unix socket (`~/.config/zurm/server.sock`)\n- Sessions persist after zurm closes; reattach restores from a 64KB output replay buffer\n- Server auto-starts on first Cmd+Shift+B and stays alive in the background\n- `[SERVER]` indicator appears in the status bar for server-backed panes\n- If the server is unreachable, panes fall back to a local PTY silently\n\n### Config\n\n```toml\n[server]\naddress = \"\"   # Unix socket path; empty = ~/.config/zurm/server.sock\nbinary  = \"\"   # zurm-server binary path; empty = next to zurm or PATH\n```\n\n## Getting Started\n\nConfig file: `~/.config/zurm/config.toml` — created automatically on first launch with all defaults.\n\nA full annotated example is available at [`config.example.toml`](config.example.toml).\n\nShell hooks for command blocks (OSC 133) are installed via the command palette: `Cmd+P` → \"Install shell hooks\".\n\nAll keybindings are discoverable in-app via `Cmd+/` (help overlay) or `Cmd+P` (command palette).\n\n## Documentation\n\nhttps://zurm.dev\n\n## Optional Fonts\n\nzurm ships with JetBrains Mono embedded. For CJK characters, emoji, Nerd Font symbols, and braille, add fallback fonts to the `[font]` section in your config:\n\n```toml\n[font]\nfallbacks = [\n  \"/Users/you/Library/Fonts/NotoSansMonoCJKsc-Regular.otf\",\n  \"/Users/you/Library/Fonts/NotoEmoji-Regular.ttf\",\n  \"/Users/you/Library/Fonts/SymbolsNerdFontMono-Regular.ttf\",\n  \"/Users/you/Library/Fonts/NotoSansSymbols2-Regular.ttf\",\n]\n```\n\nFonts are tried in order when a glyph is missing from the primary font. Download them once:\n\n```bash\n# CJK (~16 MB)\ncurl -sL \"https://github.com/googlefonts/noto-cjk/raw/main/Sans/Mono/NotoSansMonoCJKsc-Regular.otf\" \\\n  -o ~/Library/Fonts/NotoSansMonoCJKsc-Regular.otf\n\n# Monochrome emoji (~2 MB)\ncurl -sL \"https://github.com/google/fonts/raw/main/ofl/notoemoji/NotoEmoji%5Bwght%5D.ttf\" \\\n  -o ~/Library/Fonts/NotoEmoji-Regular.ttf\n\n# Nerd Font symbols (~2.4 MB)\ncurl -sL \"https://github.com/ryanoasis/nerd-fonts/releases/download/v3.4.0/NerdFontsSymbolsOnly.tar.xz\" \\\n  | tar xJ -C ~/Library/Fonts/ SymbolsNerdFontMono-Regular.ttf\n\n# Braille + extra symbols (~1.2 MB)\ncurl -sL \"https://github.com/google/fonts/raw/main/ofl/notosanssymbols2/NotoSansSymbols2-Regular.ttf\" \\\n  -o ~/Library/Fonts/NotoSansSymbols2-Regular.ttf\n```\n\nColor emoji (Apple Color Emoji, Twemoji) are not supported — Ebitengine does not render color font formats. Monochrome emoji via Noto Emoji work fine.\n\n## Contributions\n\n1. Fork the repository\n2. Create a branch: `git checkout -b feat/your-feature`\n3. Commit your changes\n4. Open a pull request\n\nOpen an issue before starting significant work.\n\n## Assets\n\nFont embedded in the binary:\n\n| Font | Source | License |\n|------|--------|---------|\n| JetBrains Mono Regular | https://github.com/JetBrains/JetBrainsMono | SIL Open Font License 1.1 |\n\n## License\n\n[MIT](LICENSE)\n\n## Contact\n\n[Studio Webux](https://studiowebux.com)\n\u003cbr\u003e\ntommy@studiowebux.com\n\u003cbr\u003e\n[Discord](https://discord.gg/BG5Erm9fNv)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstudiowebux%2Fzurm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstudiowebux%2Fzurm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstudiowebux%2Fzurm/lists"}