leftopen README

The project's README from github.com/SonghaiFan/leftopen. As one markdown file: README.md.

LeftOpen Logo

LeftOpen

Native macOS Menu Bar Port Manager & CLI

See what your tools left running on localhost, identify projects, and gently close them.

Website Release Homebrew Cask macOS 14+ Apple Notarized License: MIT

English · 中文


LeftOpen menu bar panel: closable ports first, apps and system services folded away

When I have several coding agents working in parallel, dev servers and test runners keep starting up on different ports. By the end of the day there are always a few still running.

Existing tools are either too much, or only tell you "port in use" without saying which process it is or which project it came from.

So I made LeftOpen. It sits quietly in the menu bar and shows you the listening ports, the processes behind them and the projects they probably belong to. Once you've had a look, you close the ones you no longer need.

Close the doors that were left ajar, gently.


Installation

brew install --cask songhaifan/tap/leftopen

Supports Apple Silicon and Intel Macs running macOS Sonoma (14.0+). The app and bundled CLI are universal binaries, signed with a Developer ID and notarized by Apple.

Manual download

Get LeftOpen-release.zip from GitHub Releases, unzip, and move LeftOpen.app to /Applications.


Design & Features


Fixed project addresses

Dev servers move between ports; their address doesn't have to. LeftOpen bundles Portless 0.15.7 and Node 24.14.0, so there's nothing extra to install.

  1. One-time setup: Turn on Settings → Projects → Fixed addresses. macOS asks for authorization to trust a local CA, install a loopback-only HTTPS service on the selected proxy port (443 by default), and manage exact /etc/hosts entries. Only explicit Settings actions ask; project actions and background scans never do.
  2. Per project: start the project as usual, then click Enable fixed address in its port details. It's reachable at https://myapp.localhost.

How it behaves:

Earlier HTTP addresses keep working; finish the HTTPS upgrade from the same Settings page. Portless (Apache-2.0) and Node ship with their licenses.

Address settings: Settings → Projects has a single fixed-address row, with no manual port configuration. Initial setup prefers 443, automatically trying 8443–8462 on conflict within the same authorization. Successful setup remembers the selected port and includes it in opened/copied URLs. Other listeners are never stopped; failures retain copyable diagnostics. Ports are not automatically migrated while LeftOpen-launched projects run. Turning off removes managed routes but preserves bindings, certificates and the proxy without stopping project servers; stop LeftOpen-launched projects first.


Why LeftOpen? (Common Use Cases)


CLI

Available in the terminal right after installing:

# List every listening port and its owner (or: leftopen list)
leftopen

# Explain one port
leftopen 3000

# Open http://localhost:3000 in the default browser
leftopen open 3000

# Print a project's verified fixed address (e.g. https://myapp.localhost)
leftopen url myapp

# Close the process on a port (SIGTERM, asks first)
leftopen close 3000

# Structured JSON output
leftopen --json

Sample output:

LEFT OPEN
26 listening ports · 17 processes · 1 projects · 8 LAN-visible

MY PROJECTS (2)
PORT    PID      OWNER          PROCESS    AGE      SCOPE
5173    76344    visdelta       node       2h       LOCAL
         ↳ ~/Documents/visdelta
5511    4999     visdelta       node       27m      LOCAL
         ↳ ~/Documents/visdelta

APPLICATIONS (16)
PORT    PID      OWNER          PROCESS    AGE      SCOPE
5000    696      ControlCenter  Control    3d       LAN
9222    36824    Google Chrome  Chrome     5h       LOCAL

SERVICES (3)
PORT    PID      OWNER          PROCESS    AGE      SCOPE
11434   911      Ollama         ollama     1d       LOCAL

LOCAL = this Mac only · LAN = may be reachable from your local network

Development

Maintainers: one-click releases.

# Tests
swift test

# Build the app locally
LEFTOPEN_OUTPUT_DIR=dist/dev Scripts/build-app.sh

License

MIT License

leftopen (SonghaiFan/leftopen)

Searching Database…

Что это?LeftOpen — нативное macOS-приложение в строке меню и CLI, которые показывают, что слушает localhost, определяют, какому проекту или процессу принадлежит каждый порт, и позволяют аккуратно их закрывать.
Это только GUI или есть ещё и консольный инструмент?И то и другое: SwiftUI-приложение в строке меню (MenuBarExtra, без иконки в Dock) и идущий в комплекте CLI 'leftopen' с теми же правилами определения и безопасности.
Нужен ли Homebrew или что-то ещё, прежде чем пробовать?Требуется macOS Sonoma (14.0+) на Apple Silicon или Intel; Homebrew — рекомендуемый способ установки, но подойдёт и ручная загрузка zip.
Как он решает, когда принудительно убить процесс?Сначала всегда посылается SIGTERM с повторной проверкой идентичности процесса; если процесс всё ещё слушает спустя пять секунд, повторное закрытие в течение двух минут эскалируется до SIGKILL как отдельное осознанное действие.
Работает ли он и на Intel Mac, или только на Apple Silicon?Да, это универсальный бинарник, работающий и на Apple Silicon, и на Intel Mac, если стоит macOS Sonoma или новее.
Он отправляет данные наружу или что-то отслеживает?Без телеметрии и фоновых служб по умолчанию; единственный исходящий запрос — ежедневная проверка свежего релиза на GitHub, которую можно отключить в настройках.
Как он определяет, какому проекту принадлежит порт?Он поднимается от рабочей папки процесса в поисках .git, package.json, pyproject.toml, Cargo.toml или go.mod, либо определяет владеющий .app; также называет глобальные npm/python-модули и отдельные службы вроде Redis, Postgres или Ollama.
Чем это отличается от lsof или kill-port?Те инструменты лишь выдают сырые PID или неоднозначные имена процессов, а LeftOpen отслеживает рабочую папку и корень проекта, показывая полный контекст, и использует мягкий SIGTERM с перепроверкой идентичности вместо грубого kill -9.
Что такое функция фиксированных адресов проекта?Работает на встроенной копии Portless: даёт dev-серверу стабильный локальный HTTPS-адрес, который остаётся прежним, даже если базовый порт меняется между перезапусками.
Может ли он определить, открыт ли порт в локальную сеть?Да, он отличает порты, привязанные только к 127.0.0.1 (только локально), от портов на 0.0.0.0 или LAN-адресе, так что случайную открытость в сеть легко заметить.
Creator
SonghaiFan
Size
3.3 MB
Stars
129
Age
1mo
Commits · 90 Days