main.swift
90 lines 3.0 KB
Raw
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