Skip to content

feat: PortBar 3.0 — LAN-exposure marker, reliable kill, resizable popover#1

Merged
mulhamna merged 8 commits into
mainfrom
feat/lan-exposure-and-kill-fixes
Jul 8, 2026
Merged

feat: PortBar 3.0 — LAN-exposure marker, reliable kill, resizable popover#1
mulhamna merged 8 commits into
mainfrom
feat/lan-exposure-and-kill-fixes

Conversation

@mulhamna

@mulhamna mulhamna commented Jul 8, 2026

Copy link
Copy Markdown
Owner

Summary

  • Ship PortBar 3.0: a LAN-exposure marker so you can tell which listening ports other devices on your network can reach vs. local-only ports.
  • Fix the long-standing kill bug (killed ports lingered) and broaden port preview (missing browser buttons, truncated process paths, missed Docker names).
  • Polish the popover: resizable panel, hover-to-reveal full paths, clearer exposed icon, and reliable dismissal on focus loss.

Changes

Feature — LAN bind-scope

  • BindScope on PortEntry; scanner captures the bind host from lsof/docker and classifies local-only (127.0.0.1/::1) vs exposed (0.0.0.0/*/::/LAN IP), exposed-wins on multi-binding.
  • Orange broadcast icon on exposed rows (popover) and 📡 in the legacy menu title.

Fixes

  • Kill refreshes the list immediately and kills the process group (child workers die too), with a self-group guard.
  • Browser button now covers the 5xxx range and any web framework; :443 opens over https; single shared HTTP heuristic.
  • Sturdier scanner: fallback entry when ps races, Docker match despite lsof truncation, change-detection keyed on pid+port.
  • Popover dismisses on outside click / app deactivation.

UI / tooling

  • Drag-resizable popover with persisted size; flexible PROCESS column + hover bubble showing the full path.
  • New lightning-bolt app icon (generated by scripts/make_icon.swift).
  • scripts/install.sh curl installer and a dev Makefile.
  • Version bumped to 3.0; README/CLAUDE updated with an icon reference and install docs.

Test plan

  • make build — BUILD SUCCEEDED
  • Exposed row (--bind 0.0.0.0) shows the orange icon; local-only (127.0.0.1) does not
  • :5173 (Vite range) shows the browser button
  • Kill removes the row within ~1s with Watch off
  • Hover PROCESS reveals the full path; drag grip resizes and persists
  • Popover closes when clicking another app
  • Full smoke test on a clean machine before cutting the 3.0 DMG

mulhamna added 8 commits July 8, 2026 15:00
Capture the bind host from lsof/docker and classify each listening
port as local-only (127.0.0.1/::1) or LAN-exposed, resolving a port
with multiple bindings as exposed-wins.

Also make scanning sturdier: emit a fallback entry when ps races and
drops a pid instead of hiding a live port, match Docker even when lsof
truncates the process name to 9 chars, key change-detection on pid+port
so a rebind (same port, new pid) is noticed, and centralise the
HTTP/browser heuristics in shared helpers.
Kill now refreshes the list immediately (row disappears at once) and
targets the process group so dev-server child workers die too and can't
hold the port or respawn, falling back to a single-pid kill when the
target shares our own group.

Popover UI for 3.0: an orange broadcast icon flags LAN-exposed rows; the
browser button covers the 5xxx range and any web framework and opens 443
over https; the PROCESS column is flexible with a hover bubble revealing
the full path; and the panel is drag-resizable with the size persisted.
The transient NSPopover did not reliably close for this LSUIElement
accessory app. Close it explicitly on any outside mouse-down or when the
app resigns active, cleaning up the monitors in popoverDidClose.
New user-facing features (LAN-exposure marker, resizable popover) plus
the kill/scanner fixes warrant a major bump per the versioning rules.
Indigo squircle with a glowing lightning bolt, generated at every
required size by scripts/make_icon.swift (zero-dependency AppKit/CoreGraphics).
Shortcuts for building, launching, spawning test ports, and the smoke
test, so contributors can verify changes without memorising xcodebuild flags.
One-line installer that downloads the latest release DMG, copies the app
to /Applications, clears quarantine, and launches it.
Cover the LAN-exposure marker, resizable popover, curl install, an icon
reference table, and the new scanner/kill behaviour in CLAUDE.md.
@mulhamna mulhamna merged commit 5ff9902 into main Jul 8, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant