main.swift
sha256:bd1eb24434d281fe65142038c1bf217493421f5a86880c22dff7e6037d2d4700
feat(companion): add production macOS distribution path
Human
minor
⚠ breaking
24 days ago
| 1 | import AppKit |
| 2 | import Foundation |
| 3 | import KnowtationSecurity |
| 4 | import ServiceManagement |
| 5 | |
| 6 | private final class AppDelegate: NSObject, NSApplicationDelegate { |
| 7 | private let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength) |
| 8 | private var runtimeStatus = "Starting" |
| 9 | |
| 10 | func applicationDidFinishLaunching(_ notification: Notification) { |
| 11 | statusItem.button?.title = "Knowtation" |
| 12 | installMenu() |
| 13 | do { |
| 14 | try SMAppService.agent( |
| 15 | plistName: KnowtationReleaseContract.custodyLaunchAgentPlist |
| 16 | ).register() |
| 17 | runtimeStatus = "Custody ready" |
| 18 | installMenu() |
| 19 | startRuntime() |
| 20 | } catch { |
| 21 | runtimeStatus = "Setup requires approval" |
| 22 | installMenu() |
| 23 | } |
| 24 | } |
| 25 | |
| 26 | private func startRuntime() { |
| 27 | Thread.detachNewThread { |
| 28 | do { |
| 29 | _ = try RuntimeLauncher(mode: .app).run(arguments: []) |
| 30 | } catch { |
| 31 | DispatchQueue.main.async { [weak self] in |
| 32 | self?.runtimeStatus = "Runtime unavailable" |
| 33 | self?.installMenu() |
| 34 | } |
| 35 | } |
| 36 | } |
| 37 | } |
| 38 | |
| 39 | private func installMenu() { |
| 40 | let menu = NSMenu() |
| 41 | let status = NSMenuItem(title: runtimeStatus, action: nil, keyEquivalent: "") |
| 42 | status.isEnabled = false |
| 43 | menu.addItem(status) |
| 44 | menu.addItem(.separator()) |
| 45 | menu.addItem(NSMenuItem(title: "Sign In…", action: #selector(signIn), keyEquivalent: "")) |
| 46 | menu.addItem(NSMenuItem(title: "Sign Out", action: #selector(signOut), keyEquivalent: "")) |
| 47 | menu.addItem(.separator()) |
| 48 | menu.addItem(NSMenuItem(title: "Quit Knowtation", action: #selector(quit), keyEquivalent: "q")) |
| 49 | statusItem.menu = menu |
| 50 | } |
| 51 | |
| 52 | @objc private func signIn() { |
| 53 | runCompanionCommand("sign-in", pending: "Opening browser…", success: "Signed in") |
| 54 | } |
| 55 | |
| 56 | @objc private func signOut() { |
| 57 | runCompanionCommand("sign-out", pending: "Signing out…", success: "Signed out") |
| 58 | } |
| 59 | |
| 60 | private func runCompanionCommand(_ command: String, pending: String, success: String) { |
| 61 | runtimeStatus = pending |
| 62 | installMenu() |
| 63 | Thread.detachNewThread { [weak self] in |
| 64 | do { |
| 65 | let status = try RuntimeLauncher(mode: .app).run( |
| 66 | arguments: ["companion", command] |
| 67 | ) |
| 68 | DispatchQueue.main.async { |
| 69 | self?.runtimeStatus = status == 0 ? success : "Command failed" |
| 70 | self?.installMenu() |
| 71 | } |
| 72 | } catch { |
| 73 | DispatchQueue.main.async { |
| 74 | self?.runtimeStatus = "Command failed" |
| 75 | self?.installMenu() |
| 76 | } |
| 77 | } |
| 78 | } |
| 79 | } |
| 80 | |
| 81 | @objc private func quit() { |
| 82 | NSApplication.shared.terminate(nil) |
| 83 | } |
| 84 | } |
| 85 | |
| 86 | let application = NSApplication.shared |
| 87 | private let delegate = AppDelegate() |
| 88 | application.delegate = delegate |
| 89 | application.setActivationPolicy(.accessory) |
| 90 | application.run() |
File History
1 commit
sha256:bd1eb24434d281fe65142038c1bf217493421f5a86880c22dff7e6037d2d4700
feat(companion): add production macOS distribution path
Human
minor
⚠
24 days ago