cedarstalking with keyboard shortcuts
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: rename to cedarville-people-search and compile browser in band

+94 -160
+1 -1
.gitignore
··· 1 1 node_modules/ 2 2 dist/ 3 3 .DS_Store 4 - assets/auth-browser-bin 4 + assets/compiled_raycast_swift/
+1 -1
README.md
··· 1 - # CedarStalk 1 + # Cedarville People Search 2 2 3 3 ![detail of a user](./media/cedarstalk-1.png) 4 4
+7 -57
assets/auth-browser.swift
··· 4 4 5 5 let TARGET_HOST = "selfservice.cedarville.edu" 6 6 let AUTH_COOKIES: Set<String> = [".ASPXAUTH", "studentselfservice_live"] 7 - let CONFIG_FILE = "/tmp/cedarstalk-auth-config.json" 8 - 9 - struct Config: Decodable { 10 - let signInUrl: String 11 - let cookieFile: String 12 - let logFile: String 13 - } 14 - 15 - func readConfig() -> (Config, URL)? { 16 - guard let configData = try? Data(contentsOf: URL(fileURLWithPath: CONFIG_FILE)), 17 - let config = try? JSONDecoder().decode(Config.self, from: configData), 18 - let signInURL = URL(string: config.signInUrl) 19 - else { return nil } 20 - return (config, signInURL) 21 - } 7 + let SIGN_IN_URL = URL(string: "https://selfservice.cedarville.edu/cedarinfo/directory")! 8 + let COOKIE_FILE = "/tmp/cedarsearch-cookie.txt" 22 9 23 10 class CookieObserver: NSObject, WKHTTPCookieStoreObserver { 24 11 weak var browser: AuthBrowser? ··· 28 15 } 29 16 30 17 class AuthBrowser: NSObject, NSApplicationDelegate, WKNavigationDelegate, NSWindowDelegate { 31 - let signInURL: URL 32 - let config: Config 33 18 var window: NSWindow! 34 19 var webView: WKWebView! 35 20 var cookieObserver: CookieObserver! 36 21 var didComplete = false 37 22 38 - init(url: URL, config: Config) { 39 - self.signInURL = url 40 - self.config = config 41 - super.init() 42 - } 43 - 44 - func log(_ msg: String) { 45 - let line = "[auth-browser] \(msg)\n" 46 - fputs(line, stderr) 47 - if let data = line.data(using: .utf8) { 48 - if let fh = FileHandle(forWritingAtPath: config.logFile) { 49 - fh.seekToEndOfFile(); fh.write(data); fh.closeFile() 50 - } else { 51 - try? data.write(to: URL(fileURLWithPath: config.logFile)) 52 - } 53 - } 54 - } 55 - 56 23 func applicationDidFinishLaunching(_: Notification) { 57 24 let wkConfig = WKWebViewConfiguration() 58 25 wkConfig.websiteDataStore = .nonPersistent() ··· 72 39 backing: .buffered, 73 40 defer: false 74 41 ) 75 - window.title = "CedarStalk — Sign In" 42 + window.title = "Cedarville People Search — Sign In" 76 43 window.contentView = webView 77 44 window.delegate = self 78 45 window.center() 79 46 window.makeKeyAndOrderFront(nil) 80 47 NSApp.activate(ignoringOtherApps: true) 81 48 82 - log("loading \(signInURL.absoluteString)") 83 - webView.load(URLRequest(url: signInURL)) 49 + webView.load(URLRequest(url: SIGN_IN_URL)) 84 50 } 85 51 86 52 func webView(_ webView: WKWebView, didFinish _: WKNavigation!) { 87 - log("didFinish: \(webView.url?.absoluteString ?? "nil")") 88 53 checkCookies(in: webView.configuration.websiteDataStore.httpCookieStore) 89 54 } 90 55 ··· 92 57 guard !didComplete else { return } 93 58 cookieStore.getAllCookies { [weak self] all in 94 59 guard let self, !self.didComplete else { return } 95 - if !all.isEmpty { 96 - let summary = all.map { "\($0.domain)/\($0.name)" }.joined(separator: ", ") 97 - self.log("cookies (\(all.count)): \(summary)") 98 - } 99 60 let site = all.filter { $0.domain.contains(TARGET_HOST) } 100 61 guard site.contains(where: { AUTH_COOKIES.contains($0.name) }) else { return } 101 62 102 63 self.didComplete = true 103 64 let cookieStr = site.map { "\($0.name)=\($0.value)" }.joined(separator: "; ") 104 65 // Write non-atomically so the pre-created 0o600 permissions are preserved. 105 - try? cookieStr.write(toFile: self.config.cookieFile, atomically: false, encoding: .utf8) 106 - self.log("auth complete, wrote cookie") 66 + try? cookieStr.write(toFile: COOKIE_FILE, atomically: false, encoding: .utf8) 107 67 NSApp.terminate(nil) 108 68 } 109 69 } ··· 111 71 func applicationShouldTerminateAfterLastWindowClosed(_: NSApplication) -> Bool { true } 112 72 113 73 func windowWillClose(_: Notification) { 114 - if !didComplete { 115 - log("window closed without completing auth") 116 - exit(1) 117 - } 74 + if !didComplete { exit(1) } 118 75 } 119 76 } 120 77 121 - guard let (config, signInURL) = readConfig() else { 122 - fputs("auth-browser: failed to read config from \(CONFIG_FILE)\n", stderr) 123 - exit(1) 124 - } 125 - 126 - try? "".write(toFile: config.logFile, atomically: true, encoding: .utf8) 127 - 128 78 let app = NSApplication.shared 129 - let delegate = AuthBrowser(url: signInURL, config: config) 79 + let delegate = AuthBrowser() 130 80 app.setActivationPolicy(.regular) 131 81 app.delegate = delegate 132 82 app.run()
+29 -50
bun.lock
··· 5 5 "": { 6 6 "name": "cedarstalk", 7 7 "dependencies": { 8 - "@raycast/api": "^1.93.2", 8 + "@raycast/api": "^1.104.9", 9 9 }, 10 10 "devDependencies": { 11 - "@raycast/utils": "^1.17.0", 12 11 "@types/node": "^22.13.10", 13 12 "@types/react": "^19.0.10", 14 13 "typescript": "^5.8.2", ··· 16 15 }, 17 16 }, 18 17 "packages": { 19 - "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="], 18 + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.4", "", { "os": "aix", "cpu": "ppc64" }, "sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q=="], 20 19 21 - "@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="], 20 + "@esbuild/android-arm": ["@esbuild/android-arm@0.27.4", "", { "os": "android", "cpu": "arm" }, "sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ=="], 22 21 23 - "@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="], 22 + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.4", "", { "os": "android", "cpu": "arm64" }, "sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw=="], 24 23 25 - "@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="], 24 + "@esbuild/android-x64": ["@esbuild/android-x64@0.27.4", "", { "os": "android", "cpu": "x64" }, "sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw=="], 26 25 27 - "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="], 26 + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ=="], 28 27 29 - "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="], 28 + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw=="], 30 29 31 - "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="], 30 + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.4", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw=="], 32 31 33 - "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="], 32 + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.4", "", { "os": "freebsd", "cpu": "x64" }, "sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ=="], 34 33 35 - "@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="], 34 + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.4", "", { "os": "linux", "cpu": "arm" }, "sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg=="], 36 35 37 - "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="], 36 + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA=="], 38 37 39 - "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="], 38 + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.4", "", { "os": "linux", "cpu": "ia32" }, "sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA=="], 40 39 41 - "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="], 40 + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.4", "", { "os": "linux", "cpu": "none" }, "sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA=="], 42 41 43 - "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="], 42 + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.4", "", { "os": "linux", "cpu": "none" }, "sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw=="], 44 43 45 - "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="], 44 + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA=="], 46 45 47 - "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="], 46 + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.4", "", { "os": "linux", "cpu": "none" }, "sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw=="], 48 47 49 - "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="], 48 + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA=="], 50 49 51 - "@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="], 50 + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.4", "", { "os": "linux", "cpu": "x64" }, "sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA=="], 52 51 53 - "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg=="], 52 + "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.4", "", { "os": "none", "cpu": "arm64" }, "sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q=="], 54 53 55 - "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="], 54 + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.4", "", { "os": "none", "cpu": "x64" }, "sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg=="], 56 55 57 - "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.12", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A=="], 56 + "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.4", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow=="], 58 57 59 - "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="], 58 + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.4", "", { "os": "openbsd", "cpu": "x64" }, "sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ=="], 60 59 61 - "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg=="], 60 + "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.4", "", { "os": "none", "cpu": "arm64" }, "sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg=="], 62 61 63 - "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="], 62 + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.4", "", { "os": "sunos", "cpu": "x64" }, "sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g=="], 64 63 65 - "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="], 64 + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg=="], 66 65 67 - "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="], 66 + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.4", "", { "os": "win32", "cpu": "ia32" }, "sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw=="], 68 67 69 - "@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="], 68 + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.4", "", { "os": "win32", "cpu": "x64" }, "sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg=="], 70 69 71 70 "@inquirer/ansi": ["@inquirer/ansi@1.0.2", "", {}, "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ=="], 72 71 ··· 108 107 109 108 "@oclif/plugin-not-found": ["@oclif/plugin-not-found@3.2.74", "", { "dependencies": { "@inquirer/prompts": "^7.10.1", "@oclif/core": "^4.8.0", "ansis": "^3.17.0", "fast-levenshtein": "^3.0.0" } }, "sha512-6RD/EuIUGxAYR45nMQg+nw+PqwCXUxkR6Eyn+1fvbVjtb9d+60OPwB77LCRUI4zKNI+n0LOFaMniEdSpb+A7kQ=="], 110 109 111 - "@raycast/api": ["@raycast/api@1.104.9", "", { "dependencies": { "@oclif/core": "^4.5.4", "@oclif/plugin-autocomplete": "^3.2.35", "@oclif/plugin-help": "^6.2.33", "@oclif/plugin-not-found": "^3.2.68", "@types/node": "22.13.10", "@types/react": "19.0.10", "esbuild": "^0.25.10", "react": "19.0.0" }, "peerDependencies": { "react-devtools": "6.1.1" }, "optionalPeers": ["react-devtools"], "bin": { "ray": "bin/run.js" } }, "sha512-Y75OUUhCHCag/ZWd/CB4avuNHNUQWwlbuO4pgadtBuvHOlpKVE4JZCN7nWbO4Wd/zkyfmToo3ZT53AFkugsBcQ=="], 112 - 113 - "@raycast/utils": ["@raycast/utils@1.19.1", "", { "dependencies": { "cross-fetch": "^3.1.6", "dequal": "^2.0.3", "object-hash": "^3.0.0", "signal-exit": "^4.0.2", "stream-chain": "^2.2.5", "stream-json": "^1.8.0" }, "peerDependencies": { "@raycast/api": ">=1.69.0" } }, "sha512-/udUGcTZCgZZwzesmjBkqG5naQZTD/ZLHbqRwkWcF+W97vf9tr9raxKyQjKsdZ17OVllw2T3sHBQsVUdEmCm2g=="], 110 + "@raycast/api": ["@raycast/api@1.104.11", "", { "dependencies": { "@oclif/core": "^4.8.4", "@oclif/plugin-autocomplete": "^3.2.40", "@oclif/plugin-help": "^6.2.37", "@oclif/plugin-not-found": "^3.2.74", "@types/node": "22.13.10", "@types/react": "19.0.10", "esbuild": "^0.27.3", "react": "19.0.0" }, "peerDependencies": { "react-devtools": "6.1.1" }, "optionalPeers": ["react-devtools"], "bin": { "ray": "bin/run.js" } }, "sha512-UaLyWDlgtgyruTVclcJ1RAJjRWKc/ISw+WQAzTHui4qpY3olaaXWrE/dox6/7Cd3mFZtkQ6grhdUiYTBsUUfuw=="], 114 111 115 112 "@types/node": ["@types/node@22.19.15", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg=="], 116 113 ··· 142 139 143 140 "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], 144 141 145 - "cross-fetch": ["cross-fetch@3.2.0", "", { "dependencies": { "node-fetch": "^2.7.0" } }, "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q=="], 146 - 147 142 "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], 148 143 149 144 "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], 150 - 151 - "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="], 152 145 153 146 "ejs": ["ejs@3.1.10", "", { "dependencies": { "jake": "^10.8.5" }, "bin": { "ejs": "bin/cli.js" } }, "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA=="], 154 147 155 148 "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], 156 149 157 - "esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="], 150 + "esbuild": ["esbuild@0.27.4", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.4", "@esbuild/android-arm": "0.27.4", "@esbuild/android-arm64": "0.27.4", "@esbuild/android-x64": "0.27.4", "@esbuild/darwin-arm64": "0.27.4", "@esbuild/darwin-x64": "0.27.4", "@esbuild/freebsd-arm64": "0.27.4", "@esbuild/freebsd-x64": "0.27.4", "@esbuild/linux-arm": "0.27.4", "@esbuild/linux-arm64": "0.27.4", "@esbuild/linux-ia32": "0.27.4", "@esbuild/linux-loong64": "0.27.4", "@esbuild/linux-mips64el": "0.27.4", "@esbuild/linux-ppc64": "0.27.4", "@esbuild/linux-riscv64": "0.27.4", "@esbuild/linux-s390x": "0.27.4", "@esbuild/linux-x64": "0.27.4", "@esbuild/netbsd-arm64": "0.27.4", "@esbuild/netbsd-x64": "0.27.4", "@esbuild/openbsd-arm64": "0.27.4", "@esbuild/openbsd-x64": "0.27.4", "@esbuild/openharmony-arm64": "0.27.4", "@esbuild/sunos-x64": "0.27.4", "@esbuild/win32-arm64": "0.27.4", "@esbuild/win32-ia32": "0.27.4", "@esbuild/win32-x64": "0.27.4" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ=="], 158 151 159 152 "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], 160 153 ··· 190 183 191 184 "mute-stream": ["mute-stream@2.0.0", "", {}, "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA=="], 192 185 193 - "node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], 194 - 195 - "object-hash": ["object-hash@3.0.0", "", {}, "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="], 196 - 197 186 "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], 198 187 199 188 "picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], ··· 206 195 207 196 "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], 208 197 209 - "stream-chain": ["stream-chain@2.2.5", "", {}, "sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA=="], 210 - 211 - "stream-json": ["stream-json@1.9.1", "", { "dependencies": { "stream-chain": "^2.2.5" } }, "sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw=="], 212 - 213 198 "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], 214 199 215 200 "strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], ··· 217 202 "supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="], 218 203 219 204 "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], 220 - 221 - "tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="], 222 205 223 206 "type-fest": ["type-fest@0.21.3", "", {}, "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w=="], 224 207 225 208 "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], 226 209 227 210 "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], 228 - 229 - "webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="], 230 - 231 - "whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="], 232 211 233 212 "widest-line": ["widest-line@3.1.0", "", { "dependencies": { "string-width": "^4.0.0" } }, "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg=="], 234 213
+2 -2
package-lock.json
··· 1 1 { 2 - "name": "cedarstalk", 2 + "name": "cedarville-people-search", 3 3 "lockfileVersion": 3, 4 4 "requires": true, 5 5 "packages": { 6 6 "": { 7 - "name": "cedarstalk", 7 + "name": "cedarville-people-search", 8 8 "license": "MIT", 9 9 "dependencies": { 10 10 "@raycast/api": "^1.104.9"
+6 -7
package.json
··· 1 1 { 2 2 "$schema": "https://www.raycast.com/schemas/extension.json", 3 - "name": "cedarstalk", 4 - "title": "CedarStalk", 3 + "name": "cedarville-people-search", 4 + "title": "Cedarville People Search", 5 5 "description": "Search the Cedarville University student/staff directory", 6 6 "icon": "icon.png", 7 7 "author": "taciturnaxolotl", ··· 30 30 } 31 31 ], 32 32 "dependencies": { 33 - "@raycast/api": "^1.104.9" 33 + "@raycast/api": "^1.104.11" 34 34 }, 35 35 "devDependencies": { 36 - "@types/node": "^22.13.10", 37 - "@types/react": "^19.0.10", 38 - "typescript": "^5.8.2" 36 + "@types/node": "^22.19.15", 37 + "@types/react": "^19.2.14", 38 + "typescript": "^5.9.3" 39 39 }, 40 40 "scripts": { 41 - "prebuild": "swiftc -O assets/auth-browser.swift -target arm64-apple-macos13 -o /tmp/cedarstalk-auth-arm64 && swiftc -O assets/auth-browser.swift -target x86_64-apple-macos13 -o /tmp/cedarstalk-auth-x86_64 && lipo -create -output assets/auth-browser-bin /tmp/cedarstalk-auth-arm64 /tmp/cedarstalk-auth-x86_64 && codesign --sign - --force assets/auth-browser-bin", 42 41 "build": "ray build", 43 42 "dev": "ray develop", 44 43 "fix-lint": "ray lint --fix",
+47 -37
src/auth.ts
··· 1 - import { environment, LocalStorage } from "@raycast/api"; 1 + import { environment, LocalStorage, showToast, Toast } from "@raycast/api"; 2 2 import { exec, spawn } from "child_process"; 3 - import { access, mkdir, readFile, symlink, unlink, writeFile } from "fs/promises"; 3 + import { mkdir, readFile, stat, symlink, unlink, writeFile } from "fs/promises"; 4 4 import * as os from "os"; 5 5 import * as path from "path"; 6 6 import { promisify } from "util"; ··· 8 8 const execAsync = promisify(exec); 9 9 const COOKIE_KEY = "session_cookie"; 10 10 11 - // Use /tmp directly (not os.tmpdir) so paths match the Swift binary's hardcoded CONFIG_FILE. 11 + // Use /tmp directly (not os.tmpdir) so paths match the Swift binary's hardcoded path. 12 12 // os.tmpdir() under Raycast returns /var/folders/…/T which differs from /tmp. 13 - const CONFIG_FILE = "/tmp/cedarstalk-auth-config.json"; 14 - const COOKIE_FILE = "/tmp/cedarstalk-cookie.txt"; 15 - const LOG_FILE = "/tmp/cedarstalk-auth.log"; 13 + const COOKIE_FILE = "/tmp/cedarsearch-cookie.txt"; 16 14 17 15 // ─── Cookie storage ──────────────────────────────────────────────────────── 18 16 ··· 43 41 // ─── Auth browser ────────────────────────────────────────────────────────── 44 42 45 43 // Opens an isolated WKWebView window via a temporary .app bundle so macOS 46 - // grants it proper window-server access. Config is passed via a JSON file 47 - // (not --args) to avoid Launch Services caching stale arguments. 48 - export async function launchAuthBrowser(signInUrl: string): Promise<string> { 44 + // grants it proper window-server access via Launch Services. 45 + // 46 + // The Swift source in assets/auth-browser.swift is compiled on first launch 47 + // and cached in supportPath — no pre-built binary is shipped with the 48 + // extension. Compilation requires the Xcode Command Line Tools (swiftc). 49 + export async function launchAuthBrowser(): Promise<string> { 49 50 const binaryPath = await ensureBinary(); 50 51 const appBundle = await ensureAppBundle(binaryPath); 51 52 52 - // Write config before launch — Swift reads this instead of using --args 53 53 await unlink(COOKIE_FILE).catch(() => {}); 54 - await unlink(LOG_FILE).catch(() => {}); 55 54 // Pre-create with owner-only permissions so the cookie is never world-readable. 56 55 // Swift writes non-atomically to preserve these permissions. 57 56 await writeFile(COOKIE_FILE, "", { mode: 0o600 }); 58 - await writeFile(CONFIG_FILE, JSON.stringify({ signInUrl, cookieFile: COOKIE_FILE, logFile: LOG_FILE })); 59 57 60 58 await new Promise<void>((resolve, reject) => { 61 59 const proc = spawn("open", ["-n", "-W", appBundle], { stdio: "ignore" }); ··· 63 61 proc.on("error", reject); 64 62 }); 65 63 66 - const log = await readFile(LOG_FILE, "utf-8").catch(() => "(no log)"); 67 - await unlink(LOG_FILE).catch(() => {}); 68 - 69 64 const cookie = await readFile(COOKIE_FILE, "utf-8").then((s) => s.trim()).catch(() => ""); 70 65 await unlink(COOKIE_FILE).catch(() => {}); 71 - await unlink(CONFIG_FILE).catch(() => {}); 72 66 73 - if (!cookie) throw new Error(`Sign-in cancelled. Log:\n${log}`); 67 + if (!cookie) throw new Error("Sign-in cancelled."); 74 68 return cookie; 75 69 } 76 70 71 + // Compile assets/auth-browser.swift on first launch; cache in supportPath. 72 + // Recompiles automatically if the Swift source is newer than the cached binary 73 + // (e.g. after an extension update or a stale binary from a previous approach). 77 74 async function ensureBinary(): Promise<string> { 78 - if (!environment.isDevelopment) { 79 - const binaryPath = path.join(environment.assetsPath, "auth-browser-bin"); 80 - const valid = await execAsync(`codesign --verify "${binaryPath}"`).then(() => true).catch(() => false); 81 - if (!valid) await execAsync(`codesign --sign - --force "${binaryPath}"`); 82 - return binaryPath; 75 + const binaryPath = path.join(environment.supportPath, "auth-browser"); 76 + const swiftSrc = path.join(environment.assetsPath, "auth-browser.swift"); 77 + try { 78 + const [binStat, srcStat] = await Promise.all([stat(binaryPath), stat(swiftSrc)]); 79 + if (binStat.mtimeMs >= srcStat.mtimeMs) return binaryPath; 80 + // source is newer — fall through to recompile 81 + } catch { 82 + // binary doesn't exist yet — fall through to compile 83 83 } 84 84 85 - const swiftSrc = path.join(environment.assetsPath, "auth-browser.swift"); 86 - const binaryPath = path.join(environment.supportPath, "auth-browser"); 85 + const hasSwiftc = await execAsync("xcrun --find swiftc").then(() => true).catch(() => false); 86 + if (!hasSwiftc) { 87 + await showToast({ 88 + style: Toast.Style.Failure, 89 + title: "Xcode Command Line Tools required", 90 + message: "Run `xcode-select --install` in Terminal, then try again.", 91 + }); 92 + throw new Error("swiftc not found — install Xcode Command Line Tools"); 93 + } 94 + 95 + await mkdir(environment.supportPath, { recursive: true }); 87 96 97 + const toast = await showToast({ style: Toast.Style.Animated, title: "Compiling sign-in helper…" }); 88 98 try { 89 - await access(binaryPath); 90 - return binaryPath; 91 - } catch { 92 - await mkdir(environment.supportPath, { recursive: true }); 93 - await execAsync(`swiftc -O "${swiftSrc}" -o "${binaryPath}"`); 94 - await execAsync(`codesign --sign - --force "${binaryPath}"`); 95 - return binaryPath; 99 + // Use `xcrun swiftc` (not the raw path) so xcrun sets up DEVELOPER_DIR and 100 + // the correct SDK — running the swiftc binary directly loses that context. 101 + await execAsync(`xcrun swiftc -O "${swiftSrc}" -o "${binaryPath}"`); 102 + } finally { 103 + await toast.hide(); 96 104 } 105 + 106 + return binaryPath; 97 107 } 98 108 99 109 async function ensureAppBundle(binaryPath: string): Promise<string> { 100 - const appDir = path.join(os.tmpdir(), "CedarStalkAuth.app"); 110 + const appDir = path.join(os.tmpdir(), "CedarvilleAuth.app"); 101 111 const macosDir = path.join(appDir, "Contents", "MacOS"); 102 112 const plistPath = path.join(appDir, "Contents", "Info.plist"); 103 - const bundledBinary = path.join(macosDir, "CedarStalkAuth"); 113 + const bundledBinary = path.join(macosDir, "auth-browser"); 104 114 105 - // Always recreate fresh so LS sees a new bundle 115 + // Always recreate fresh so Launch Services sees a new bundle. 106 116 await execAsync(`rm -rf "${appDir}"`).catch(() => {}); 107 117 await mkdir(macosDir, { recursive: true }); 108 118 await symlink(binaryPath, bundledBinary); ··· 112 122 <plist version="1.0"> 113 123 <dict> 114 124 \t<key>CFBundlePackageType</key><string>APPL</string> 115 - \t<key>CFBundleExecutable</key><string>CedarStalkAuth</string> 116 - \t<key>CFBundleIdentifier</key><string>sh.dunkirk.cedarstalk.auth</string> 117 - \t<key>CFBundleName</key><string>CedarStalk Auth</string> 125 + \t<key>CFBundleExecutable</key><string>auth-browser</string> 126 + \t<key>CFBundleIdentifier</key><string>sh.dunkirk.cedarville-people-search.auth</string> 127 + \t<key>CFBundleName</key><string>Cedarville Auth</string> 118 128 \t<key>NSPrincipalClass</key><string>NSApplication</string> 119 129 \t<key>NSHighResolutionCapable</key><true/> 120 130 \t<key>LSMinimumSystemVersion</key><string>13.0</string>
+1 -5
src/search-directory.tsx
··· 35 35 import { getCacheSize, mergePeopleIntoCache, searchCache } from "./cache"; 36 36 import { getCachedPhotoPath } from "./images"; 37 37 38 - const SIGN_IN_URL = "https://selfservice.cedarville.edu/cedarinfo/directory"; 39 38 40 39 type AuthState = 41 40 | { kind: "loading" } ··· 666 665 useEffect(() => { 667 666 (async () => { 668 667 let cookie = await getStoredCookie(); 669 - 670 - // Raycast may have closed mid-auth while the Swift browser was still 671 - // running. If it finished and wrote the cookie file, pick it up now. 672 668 if (!cookie) { 673 669 const pending = await drainPendingCookie(); 674 670 if (pending) { ··· 805 801 message: "Complete login in the window that opens", 806 802 }); 807 803 try { 808 - const cookie = await launchAuthBrowser(SIGN_IN_URL); 804 + const cookie = await launchAuthBrowser(); 809 805 await storeCookie(cookie); 810 806 toast.style = Toast.Style.Success; 811 807 toast.title = "Signed in!";