Skip to content
JessePeplinskiPublic

About

Native macOS menu-bar command center for local development services and deployment status.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

PortDeck

PortDeck is a native macOS menu-bar command center for local development services and read-only deployment-provider health.

Important

PortDeck is in pre-release development. v0.1.0-beta.18 is the current signed and notarized GitHub prerelease. Beta.13 introduced signed Sparkle updates. Source-development, sandbox-probe, local release-candidate, and production direct-download artifacts remain separate workflows.

What PortDeck does

  • Discovers listening ports, processes, Git repositories and worktrees, and Docker services on the local Mac.
  • Groups running services by project and worktree, with focused open, inspect, and confirmed stop controls.
  • Shows read-only production and deployment health for Vercel, Convex, GitHub Actions, Supabase, Cloudflare, Railway, Fly.io, Netlify, and Hostinger.
  • Keeps provider tabs configurable without changing the underlying discovery or provider contracts.

Provider views are observation surfaces. They use existing authenticated sessions owned by the providers' official CLIs and do not deploy, restart, configure, or delete remote resources. Local stop controls act only on currently discovered process or Docker identities after explicit confirmation.

Install the Apple Silicon beta

The current beta supports arm64 Apple Silicon Macs running macOS 14 or newer. Install it with Homebrew:

brew install --cask JessePeplinski/tap/portdeck@beta
open -a PortDeck

Homebrew installs the same signed and notarized app published on GitHub. For a manual installation, download the DMG, open it, and drag PortDeck into Applications:

Download both files into the same directory, verify the disk image, then open it:

shasum -a 256 -c PortDeck-0.1.0-beta.18-macos-arm64.dmg.sha256
open PortDeck-0.1.0-beta.18-macos-arm64.dmg

The versioned ZIP and checksum remain on the GitHub Release for Homebrew and fallback installs. Both containers hold the same Developer ID-signed, Apple-notarized app. PortDeck does not use App Sandbox in the direct-download build because local process, port, Git, Docker, stop controls, and external provider CLI access require the separately verified direct-download boundary.

Provider tabs stay available even when their CLI is missing. PortDeck shows the exact install command, official documentation, and a Refresh action; it never installs or upgrades provider CLIs automatically. The current supported ranges are:

Provider Supported CLI
Convex >=1.42.1 <2.0.0
Supabase >=2.109.1 <3.0.0
Cloudflare Wrangler >=4.111.0 <5.0.0
Railway >=5.26.2 <6.0.0
Fly.io flyctl >=0.4.71 <0.5.0
Netlify >=26.2.0 <27.0.0, Node.js >=20.12.2
Hostinger >=3.7.0 <4.0.0

Vercel and GitHub continue to use their existing external CLI contracts.

Run from source

Requirements

  • macOS 14 or newer
  • Xcode with a Swift 6 toolchain
  • Node.js and npm

From the repository root:

npm ci
npm run verify
portdeck-mac/scripts/run-dev-app.sh

The launcher builds and opens PortDeck.app; PortDeck then appears in the menu bar. The source workflow resolves the JavaScript discovery helper from this checkout and provider CLIs from the user's login shell or standard Homebrew locations.

Build the local arm64 release candidate

After npm ci, build and verify the self-contained local-discovery candidate from the repository root:

npm run build:mac:release
npm run verify:mac:release

The artifact is written to portdeck-mac/.build/release-artifacts/PortDeck.app. It bundles the PortDeck helper, the official arm64 Node.js 24.18.0 binary, and the arm64 Sparkle runtime, so local discovery and confirmed service stops do not require this checkout, a PortDeck CLI installation, or a system Node.js installation. Provider CLIs are intentionally external. The verifier copies the app outside the checkout, scrubs PATH, exercises the status contract, enforces a 110 MiB app budget and 72-file ceiling, validates Sparkle's nested signatures, and launches the copied app.

This artifact is a local packaging candidate, not the public ZIP. It has no production icon, Developer ID signature, or notarization ticket. It is ad-hoc signed with hardened runtime, does not enable App Sandbox, and is expected to fail Gatekeeper assessment.

Repository layout

The static marketing site is maintained independently in portdeck-site. This repository owns the CLI/helper, Mac app, product documentation, release scripts, tags, and downloadable assets.

Privacy and trust

  • PortDeck never bundles provider credentials or copies them into PortDeck-owned storage.
  • Provider commands are read-only and scoped to the data PortDeck renders.
  • PortDeck does not modify monitored projects, their manifests, lockfiles, CLI context, or remote resources.
  • Command failures are bounded and credential-redacted before they reach the UI.
  • PortDeck does not keep project launch commands or manage project process groups.

See docs/architecture.md for the detailed provider allowlists and failure behavior.

Production direct-download release pipeline

The production pipeline is deliberately separate from build:mac, run-dev-app.sh, the sandbox probe, and the local ad-hoc candidate. It:

  1. Uses the approved, checksum-pinned production .icns in portdeck-mac/Resources, and requires a valid Developer ID Application identity and notarytool Keychain profile.
  2. Builds the arm64 release app with the bundled local-discovery helper, Node.js runtime, and Sparkle 2.9.4 framework; strips bundled Mach-O code; and keeps matching Swift debug symbols outside the app.
  3. Excludes every provider CLI and provider dependency tree from the bundle.
  4. Signs every nested Mach-O and Sparkle helper app inside-out with hardened runtime and secure timestamps, then signs the outer app without App Sandbox.
  5. Notarizes a temporary ZIP, inspects the accepted log, staples the ticket to PortDeck.app, and creates the final ZIP with ditto -c -k --keepParent.
  6. Creates a drag-to-Applications DMG with create-dmg, signs and separately notarizes the disk image, then staples the DMG ticket.
  7. Verifies the final ZIP and DMG outside the repository under simulated quarantine, isolated state and home directories, and a scrubbed PATH, with hard limits of 110 MiB installed, 45,000,000 ZIP bytes, and 55,000,000 DMG bytes.

Install the Finder-layout dependency with brew install create-dmg, then run the release preflight with npm run preflight:mac:github-release. It checks the packaging tools, local signing metadata, and selected notarytool profile with a silent, read-only Apple Notary history request when the profile is not visible through the legacy Keychain lookup; it never uploads an artifact. The signing-and-notarization build is additionally guarded by PORTDECK_APPROVE_SIGNING_AND_NOTARIZATION=YES and must not run until the release owner explicitly approves signing and the Apple uploads. See docs/distribution.md for the complete commands, fixed inputs, and verification contract.

Beginning with beta.13, signed manual and Homebrew installations check the signed beta appcast daily. PortDeck surfaces a quiet New version available action in the menu and keeps Check for Updates… in Settings; Sparkle does not silently install updates and system profiling is disabled. Development builds do not contact the production feed. Sparkle updates use the full Developer ID-signed and notarized DMG so emergency key rotation remains possible; Homebrew continues to install the matching ZIP. Delta updates, a universal/x86_64 package, and App Store distribution remain outside this beta.

Contributing

Read AGENTS.md before making changes. Keep changes focused, preserve the discovery and read-only provider boundaries, and run npm run verify before opening a pull request.

PortDeck is available under the MIT License.

About

Native macOS menu-bar command center for local development services and deployment status.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages