Skip to content

achekulaev/lowcal

Repository files navigation

Lowcal app icon

Lowcal Terminal Orchestrator

A small desktop app for keeping a tidy stable stack of dev terminals — one tab per project / service, each backed by a real interactive PTY, each remembering its own working directory, environment, command, and tags. Group profiles by tag folders. Start / Stop whole tags at once.

Built with Tauri 2 (Rust) + React + TypeScript + xterm.js, so the bundle is a small native .app rather than an Electron-sized download. macOS is the primary target today (hidden titlebar + traffic-light overlay tuned for the sidebar header), but the Tauri shell and the PTY layer (portable-pty) are cross-platform; Windows / Linux builds should work and just won't get the macOS-specific chrome polish.

Lowcal Terminal Orchestrator UI


Why

A normal terminal multiplexer (tmux, iTerm tabs, VS Code's terminal) is fine for one project. As soon as a workday means "start the API, start the worker, start the web dev server, tail this log, attach to that container, keep a free shell for ad-hoc", the friction adds up:

  • You retype (or up-arrow-fish) the same cd … && npm run dev for each tab.
  • You can't tell at a glance which sessions are actually up.
  • "Stop everything for this project" means clicking through eight tabs.
  • A wedged foreground job (Docker Compose, a hung dev server) needs a manual Ctrl+C.
  • When something exits with a non-zero code in the background, you don't notice until you switch back to its tab.

Lowcal Terminal Orchestrator makes each of those things a button:

  • The command, cwd, env and tags live in a YAML file the app owns.
  • A coloured status dot per tab — green for running, gray for stopped, red when a Start-injected command exited non-zero (with the exit code surfaced on hover).
  • Tags in the sidebar let you group, and bulk-start/stop projects.

Tech stack

Layer Tech
Shell / packaging Tauri 2 (Rust)
Frontend React 18 + TypeScript + Vite
Terminal renderer xterm.js + @xterm/addon-fit
PTY portable-pty
PTY ↔ frontend bridge axum WebSocket on 127.0.0.1:<dynamic>
Config YAML via serde_yaml, watched with notify
Native dialogs tauri-plugin-dialog

Requirements

  • macOS (primary), or Linux / Windows for unsupported-but-likely-works builds.
  • Node.js 18+ and npm.
  • Rust toolchain (stable). Install via rustup.
  • Tauri 2 prerequisites for your OS — see Tauri's prerequisites guide. On macOS that's Xcode Command Line Tools (xcode-select --install).

Getting started (dev)

git clone https://github.com/achekulaev/lowcal.git
cd lowcal
npm install
npm run tauri dev

The Tauri dev command starts Vite on http://localhost:1420, builds the Rust side, and launches the desktop window with hot reload for the frontend.

On first launch, Lowcal copies terminals.example.yaml into the OS app config directory as terminals.yaml. Edit it from inside the app (right-click a profile → Edit, or + for a new one) or directly on disk — external saves are watched and prompt to reload.


Build a release .app

npm run tauri build

This runs the frontend build (tsc && vite build) and produces:

  • src-tauri/target/release/bundle/macos/LowCal.app
  • src-tauri/target/release/bundle/dmg/LowCal_<version>_<arch>.dmg

Tauri usually opens the DMG window after a successful build so you can drag the app into /Applications yourself.


Running on macOS (unsigned build)

LowCal is a personal-scratch project and isn't currently signed with a paid Apple Developer ID certificate, so the build you produce locally (or download from a release, if any) is ad-hoc signed. macOS Gatekeeper sees that, marks the .dmg as quarantined when it lands in ~/Downloads, and on first launch you'll get one of:

  • "LowCal" can't be opened because Apple cannot check it for malicious software.
  • "LowCal" is damaged and can't be opened. You should move it to the Trash. (This second message is misleading — the app isn't damaged, it's just quarantined and unsigned.)

Two ways past it, pick whichever you prefer:

Option A — right-click → Open (one-time, GUI):

  1. Drag LowCal.app into /Applications from the DMG.
  2. In Finder, right-click (or Control-click) the app → Open.
  3. In the warning dialog, click Open again.

macOS remembers the exception per app, so subsequent launches are normal double-clicks.

Option B — strip the quarantine flag (one-time, terminal):

xattr -dr com.apple.quarantine "/Applications/LowCal.app"

After this the app launches with a normal double-click.

If you build LowCal yourself with npm run tauri build and run it from src-tauri/target/release/bundle/macos/LowCal.app directly, you usually won't hit the quarantine dialog at all — the flag is only added by Safari, Mail, AirDrop, etc. when a file arrives from "outside".


Configuration

terminals.yaml lives in the OS app config directory (e.g. on macOS: ~/Library/Application Support/dev.lowcal.terminal-orchestrator/terminals.yaml).


Keyboard shortcuts

Shortcut Action
Cmd+T / Ctrl+T Open New terminal (create profile).
Cmd+= / Ctrl+= Same as New terminal.
Cmd+F / Ctrl+F Focus sidebar profile filter (flat-results mode).
Esc In the filter: clear and close. In the editor modal: cancel.
Cmd+Enter / Ctrl+Enter In the editor modal: save.

Status

This is a personal-scratch project that I've been finding useful enough to keep iterating on. The API and config schema may shift between minor versions; the YAML config is forward-compatible (unknown fields are preserved by the editor) but no formal migration guarantees yet.

Issues and PRs welcome, but expect slow turnaround.


License

No license is published in this repository yet. Until one is added, the default is all rights reserved — please open an issue if you'd like to use it for anything beyond evaluation.

About

Lowcal Terminal Orchestrator — a tagged PTY terminal orchestrator

Resources

Stars

Watchers

Forks

Contributors