Skip to content

Releases: ftchvs/harbor

Release list

Harbor 1.0.0

Choose a tag to compare

@ftchvs ftchvs released this 10 Jul 06:28

Changelog

All notable changes to Harbor are documented here.

The format is based on Keep a Changelog, and Harbor aims to adhere to Semantic Versioning.

[Unreleased]

[1.0.0] - 2026-07-09

Added

  • App icon and logo: a mooring bollard with a hemp rope — a harbor holds vessels safely in place, the way Harbor holds your dev servers in view — with sea-glass signal arcs for a live, listening port. Vector masters in Design/ (full icon, small-size simplified variant for 16–64 px, light/dark logo lockups), a complete macOS AppIcon.appiconset wired via ASSETCATALOG_COMPILER_APPICON_NAME, and a standalone Design/Harbor.icns.
  • Well-known-service resolver (HarborCore): identifies the port of a "Show all" listener the framework detector can't name — a curated table of macOS-specific ports (SSH, DNS, HTTP/HTTPS, SMB, AFP, Apple Remote Desktop, Bonjour/mDNS, Screen Sharing/VNC 5900–5910, AirPlay Receiver, iTunes/Device Sync) checked first, then a getservbyport(3)//etc/services fallback restricted to ports below 1024 (registered-range entries like :3000 → "hbci" collide with common dev ports and would be actively misleading). Surfaced next to the port for framework-less rows (e.g. "AirPlay Receiver :7000") and, when resolved, as a "Service" field in the detail inspector.
  • Multi-select batch kill (AND-1079): ⌘-click toggles rows in and out of a selection, Shift-click extends a contiguous range from the anchor, and a plain click collapses back to a single selection. With 2+ rows selected a "Kill N Selected" control appears in the footer; it freezes the chosen entries, shows the same enumerated "Terminate N processes?" confirmation as Kill All (gated by the same confirm preference), excludes Harbor's own process, terminates unique PIDs through the shared aggregator, and names any survivors on partial failure. Esc cancels a pending batch kill without closing the panel; arrow-key navigation returns to single-selection, and filter/exposure/refresh changes prune vanished rows from the selection.
  • Vitals sparklines (AND-1069): the detail inspector now draws CPU and memory trend sparklines for the expanded row, backed by a fixed-capacity 60-sample rolling history retained per (pid, start time) in the refresh coordinator. History accumulates across scans for a stable listener, starts a fresh series when a process restarts (its start time changes), and is dropped once the listener disappears; it is in-memory only and never survives relaunch. The Canvas-drawn sparkline scales to the retained window and renders safely for empty (muted baseline) and single-sample (flat line) series.
  • Per-port detail inspector (AND-1068): a disclosure chevron — or Space on the selected row — expands an inline, read-only accordion beneath any row, surfacing the full command line, working directory, owner app (+ bundle id), tunnel provider/endpoint, Docker/k8s origin, bind scope, address families, health, PID, and uptime. Full argv and the working directory are read lazily on a row's first expansion (never during the refresh scan); every field hides gracefully when unavailable, arrow-key selection keeps working with a panel open, and each field carries a VoiceOver label with the expansion state announced.
  • Project kickoff (2026-07-03): initial vision, roadmap, design, and engineering documentation; root scaffolding (README, CLAUDE.md, AGENTS.md, CONTRIBUTING.md, ARCHITECTURE.md, .gitignore).
  • Defined the six-milestone plan — M0 Foundation · Prove the Hard Parts, M1 Alpha · See Every Port, M2 Beta · Act on Ports, M3 Polish · Native Feel, M4 Release · Notarize & Ship, M5 Differentiate · Post-1.0 (backlog) — and the eleven epics (E1–E11), mapped 1:1 to Linear.
  • Established the five-module architecture: HarborApp, HarborCore, HarborServices, HarborUI, HarborDesignSystem.
  • Implemented the M0-M2 local beta lane: native listening-port enumeration with lsof fallback, process vitals and framework detection, menu-bar panel shell, row actions, browser open, kill/Kill All, terminal activation baseline, manual QA matrix, and green verify/smoke/release-preflight scripts.
  • Added release preflight packaging checks for a universal ad-hoc Release app, DMG creation, and SHA256 checksum generation.
  • Added a Settings surface with persisted refresh cadence and general preference controls.
  • Added production-readiness gates for product source cleanliness, local Sparkle update/install proof, Release-like GUI smoke, RC sign-off evidence, manual QA evidence validation, release-build guardrails, static-site validation, and public release-asset deploy guarding.
  • Kill All safety: Harbor's own process is excluded from every kill path, the confirmation lists the exact targets (name, port, PID), partial failures name the surviving processes, and permission errors are explained instead of showing a raw errno.
  • Rebindable global hotkey: a recorder in Settings › Shortcut captures a custom summon shortcut (modifier required, Esc cancels, inline conflict warning against Harbor's panel shortcuts) with Reset to Default and live re-registration; replaces the fixed three-preset picker.
  • "Pause refresh when panel is closed" toggle in Settings › Refresh (default on); turning it off keeps the scan stream live so reopening shows current data instantly.
  • Footer shows a live "Updated Ns ago" timestamp; removed the unreachable duplicate arrow-key handler; hotkey controller teardown uses isolated deinit.
  • New HarborAppSupport module extracts the composition root's pure logic (Sparkle gating, badge title, pause-refresh semantics, launch-at-login decisions) so it is unit-testable — the architecture is now six modules.
  • Copy suite: row context-menu actions Copy URL (⌘C), Copy PID, Copy Port, Copy Command, and Copy as curl, with IPv6-safe URL forms (2026-07-07, M5).
  • harbor:// URL scheme: show, open?port=N (opens the browser), and kill?port=N (opens Harbor's kill confirmation — never kills headlessly).
  • harbor-cli companion executable: list [--json] (works with the app closed, stable JSON output) and kill <port|pid> (prompts unless --force).
  • harbor-cli v2: watch [--json] [--interval s] streams added/removed/changed listener events until Ctrl-C (exit 0); a versioned JSON schema ({ schemaVersion, ports } envelope for list --json, one { schemaVersion, kind, port, previous? } event per line for watch --json) documented in docs/06-engineering/harbor-cli-json-schema.md; an open <port|pid> verb that opens the listener's browser URL; and committed zsh/bash/fish completions under Sources/harbor-cli/completions/.
  • Project/workspace grouping: listeners cluster under collapsible project headers derived from each process's working directory (nearest .git/package.json/Cargo.toml/… ancestor); Settings toggle, default off.
  • Notifications (both default off): "new listener appears" (exactly once per new listener, silent on launch) and "server stays high-energy" (fires only after a sustained window, kill cancels it), with 30-second coalescing and actions that open Harbor or its confirm UI.
  • Additional framework detectors — Astro, Remix, FastAPI, Phoenix, Spring Boot, Laravel — plus per-framework quick actions in the row context menu (FastAPI /docs, Django /admin, Rails /rails/info/routes, Phoenix /dev/dashboard, Spring Boot /actuator/health).
  • Docker and Kubernetes port-forward awareness: docker-proxy/Docker.app listeners show container origin (via docker ps when available), kubectl port-forward listeners show their target resource; degrades gracefully without the CLIs.
  • Tunnel awareness: ngrok (public endpoint from the local agent API), cloudflared, and ssh -R/-L tunnels are labeled with their public endpoint or target.
  • Pins, favorites & custom names: ⌘P pins rows to a stable top section (persisted), Rename… sets a custom primary label that survives restarts, and a pinned-but-stopped port shows a dimmed "Not running" placeholder.
  • Port history & quick relaunch: a "Recently stopped" section lists the last 10 killed servers with their exact command; Relaunch confirms the command and cwd before respawning, refuses occupied ports, and can optionally persist across launches.
  • Network-exposure alerts: an amber "Exposed" chip on listeners bound beyond loopback, a click-to-filter "N exposed" header count, and an optional (default-off) notification for newly exposed listeners.
  • HTTP health peek (opt-in, default off): a per-row liveness dot — green 2xx/3xx, amber 4xx/5xx, gray timeout/non-HTTP — from bounded 1-second HEAD / probes that never run while the panel is closed and refresh is paused.
  • Credentialed-release runbook (docs/06-engineering/release-runbook.md): exact one-time credential setup and per-release command sequence from green readiness lane to notarized, published 1.0.
  • Panel popover auto-resize (PR #15): the popover sizes itself to the visible port count, grows up to a maximum height and then scrolls its content internally, and live-adjusts while the panel stays open as listeners come and go.
  • Owner-app attribution: each row is labeled with the GUI application that launched the listener (iTerm2, Warp, VS Code, …) by walking process ancestry to the nearest .app bundle, with an "Unknown" fallback and VoiceOver support.
  • "Show all" toggle in the panel header (persisted, default on): switching it off curates the list to dev-relevant listeners — known framework, project, exposed, tunneled, container-forwarded, or pinned — hiding background system noise.
  • Settings › General mirrors the "Show all listeners" toggle, bound to the same preference as the panel header so either surface updates the list live and the choice persists across relaunch.
  • Menu-bar right-click quick menu: right-click (or Control-click) the status item to act without opening the panel — up to 8 l...
Read more