Skip to content
Buy · $14.99 Opens the GitHub repository in a new tab. The signed build is a separate download; see the README for what is in each.
Changelog

Bastion 1.17.0

Version 1.17.0 ·

Added

  • Help ▸ Report an Issue, Send Feedback and Bastion Support. The Help menu opens the issue tracker, a feedback form on the website and a new support page, from the same shared package the other mgcrea apps use. The app still sends nothing: each item hands your browser a URL, and the app version, macOS version, Mac model and language it carries are in the address bar and editable on the form before anything goes anywhere. The tracker stays the primary channel; the form is for reports that quote your own servers, profiles or activity log.

Changed

  • The app icon's fort sits behind the ridge instead of on top of it. Standing in front of both hills at 580 wide, the fort's 90% ink laid a pale translucent band across the ridge wherever the two crossed, and at 16px the two shapes merged into one. The fort is 24/29 of that size now and takes the ridge itself as its base — the same curve, re-expressed between its two feet — so fort and hill share one edge and never overlap. The .icon bundle, the lockup and every website favicon, touch icon and card are regenerated from the new mark. The menu bar glyphs are deliberately untouched: they still draw the fort standing on the ridge, recorded in design/README.md as a known divergence rather than quietly changed.

Fixed

  • A gateway that had died went on showing green. Gateway keeps its state behind a lock and is Sendable, with nothing for SwiftUI to subscribe to, so Gateway.shared.port read inside a view body was a value sampled once and never revisited. The menu bar panel got away with it because MenuBarExtra rebuilds its content every time it opens; the main window has no such rebuild, so the sidebar's status row could sit on "Serving on 127.0.0.1:…" indefinitely — the one line whose whole job is to beat a client's "connection refused" to you. Both read an observable projection now, published by Gateway.start() on the failure path as well as the success one.

  • The menu bar panel had a phantom gap above the gateway line when licensed. The licensed case returned an empty view from inside a TimelineView, which measures zero but remains a laid-out child, so the stack allocated spacing on both sides of nothing and the header sat 24pt above the line instead of 12. It also ran a fifteen-second timer for the lifetime of every panel open with no countdown to show for it. The licensed case contributes no view at all now, and only the trial and refused states build the timer.

  • The menu bar's trial banner offered a licence the rest of the app would not sell. Its buy button was not gated on isSelling, which the Settings licence pane has always gated its identical button on — so a build made while the store is closed answered the same question two ways depending on where you asked it.