Skip to content

feat(macos): packaged app bundle scaffolding (#165) - #166

Merged
jonocodes merged 1 commit into
mainfrom
feat/macos-app-bundle-165
Sep 23, 2026
Merged

jonocodes merged 1 commit into
mainfrom
feat/macos-app-bundle-165

Conversation

@jonocodes

Copy link
Copy Markdown
Owner

Phase 0 of #165 — the self-contained deckd.app scaffolding. Everything here builds and is testable on Linux except the AppKit wrapper and the frozen bundle itself, which need macOS.

What changed

  • Daemon seam. main() is split into parse_args() / build_server() / serve(). serve() gains install_signal_handlers (the CLI keeps the default) and an on_started task handle, so the app can run the server on a background thread where loop.add_signal_handler is illegal. _build_sinks / _overlay_dir_for are untouched.
  • deckd.macos_app. Platform-independent bundle helpers: frozen-aware resource_root(), seed-once seed_layouts() (writes to ~/Library/Application Support/deckd/layouts), app_argv(), and a thread-based ServerRunner.
  • packaging/macos/menubar.py. PyObjC status-item app (no Dock icon): Open surface / Open layouts folder / Restart server / Allow LAN access / Quit. Localhost-only until LAN is toggled.
  • packaging/macos/deckd.spec. PyInstaller recipe bundling the client (web/) and layouts; LSUIElement, bundle id com.deckd.daemon, ad-hoc signed, not notarized.
  • just build-macos-app / build-macos-dmg (refuse to run off-mac), the [packaging] extra, tests, and docs.

Verification

  • pyright daemon — clean
  • pytest — 739 passed (new tests/test_app.py covers seeding, argv, and ServerRunner start/stop)
  • just build-macos-app on Linux exits 1 with a clear message

Not verified (needs a Mac — Phase 1)

The .app build, the menu bar, and that a TCC grant sticks. PyInstaller/pyobjc hidden-import adjustments are likely. The daemon refactor is behaviour-preserving but worth an eye on the CLI error paths (password refusal now exits 2 via SystemExit instead of parser.error).

Refs #165

Phase 0 of the self-contained deckd.app: the daemon seam and the
packaging artifacts, all buildable/testable on Linux except the AppKit
wrapper.

- Split __main__.main() into parse_args()/build_server()/serve() so the
  app can construct a Server and run it on a background thread without
  installing signal handlers. Pure refactor; _build_sinks and
  _overlay_dir_for are unchanged.
- Add deckd.macos_app: resource discovery, seed-once layout install,
  argv construction, and a thread-based ServerRunner.
- Add packaging/macos/menubar.py (PyObjC status item) and deckd.spec
  (PyInstaller, LSUIElement, ad-hoc signed) plus just build-macos-app
  and build-macos-dmg.
- Add the [packaging] extra (PyInstaller), tests, and docs.

Refs #165
@jonocodes
jonocodes merged commit 9aa0818 into main Sep 23, 2026
4 checks passed
@jonocodes
jonocodes deleted the feat/macos-app-bundle-165 branch September 23, 2026 21:36
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