import SwiftUI #if canImport(FoundationModels) import FoundationModels #endif #if os(macOS) import AppKit #endif #if os(macOS) final class AppDelegate: NSObject, NSApplicationDelegate { weak var viewModel: EditorViewModel? func application(_ application: NSApplication, open urls: [URL]) { Task { @MainActor in for url in urls { self.viewModel?.openFile(url: url) } } } } #endif @main struct NeonVisionEditorApp: App { @StateObject private var viewModel = EditorViewModel() #if os(macOS) @Environment(\.openWindow) private var openWindow @State private var useAppleIntelligence: Bool = true @State private var appleAIStatus: String = "Apple Intelligence: Checking…" @State private var appleAIRoundTripMS: Double? = nil @State private var enableTranslucentWindow: Bool = UserDefaults.standard.bool(forKey: "EnableTranslucentWindow") @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate #endif @State private var showGrokError: Bool = false @State private var grokErrorMessage: String = "" var body: some Scene { #if os(macOS) WindowGroup { ContentView() .environmentObject(viewModel) .onAppear { appDelegate.viewModel = viewModel } .environment(\.showGrokError, $showGrokError) .environment(\.grokErrorMessage, $grokErrorMessage) .frame(minWidth: 600, minHeight: 400) .task { #if USE_FOUNDATION_MODELS do { let start = Date() _ = try await AppleFM.appleFMHealthCheck() let end = Date() appleAIStatus = "Apple Intelligence: Ready" appleAIRoundTripMS = end.timeIntervalSince(start) * 1000.0 } catch { appleAIStatus = "Apple Intelligence: Error — \(error.localizedDescription)" appleAIRoundTripMS = nil } #else appleAIStatus = "Apple Intelligence: Unavailable (build without USE_FOUNDATION_MODELS)" #endif } .onReceive(NotificationCenter.default.publisher(for: .toggleTranslucencyRequested)) { notif in if let enabled = notif.object as? Bool { enableTranslucentWindow = enabled if let window = NSApp.windows.first { window.isOpaque = !enabled window.backgroundColor = enabled ? .clear : NSColor.windowBackgroundColor window.titlebarAppearsTransparent = enabled } } } .onAppear { if let window = NSApp.windows.first { window.isOpaque = !enableTranslucentWindow window.backgroundColor = enableTranslucentWindow ? .clear : NSColor.windowBackgroundColor window.titlebarAppearsTransparent = enableTranslucentWindow } } } .defaultSize(width: 1000, height: 600) WindowGroup("New Window", id: "blank-window") { ContentView() .environmentObject(EditorViewModel()) .environment(\.showGrokError, $showGrokError) .environment(\.grokErrorMessage, $grokErrorMessage) .frame(minWidth: 600, minHeight: 400) } .defaultSize(width: 1000, height: 600) .commands { CommandGroup(replacing: .newItem) { Button("New Window") { openWindow(id: "blank-window") } .keyboardShortcut("n", modifiers: .command) } CommandMenu("File") { Button("New Window") { openWindow(id: "blank-window") } Button("New Tab") { viewModel.addNewTab() } .keyboardShortcut("t", modifiers: .command) Button("Open File...") { viewModel.openFile() } .keyboardShortcut("o", modifiers: .command) Button("Save") { if let tab = viewModel.selectedTab { viewModel.saveFile(tab: tab) } } .keyboardShortcut("s", modifiers: .command) .disabled(viewModel.selectedTab == nil) Button("Save As...") { if let tab = viewModel.selectedTab { viewModel.saveFileAs(tab: tab) } } .disabled(viewModel.selectedTab == nil) Button("Rename") { viewModel.showingRename = true viewModel.renameText = viewModel.selectedTab?.name ?? "Untitled" } .disabled(viewModel.selectedTab == nil) Button("Close Tab") { if let tab = viewModel.selectedTab { viewModel.closeTab(tab: tab) } } .keyboardShortcut("w", modifiers: .command) .disabled(viewModel.selectedTab == nil) } CommandMenu("Language") { ForEach(["swift", "python", "javascript", "typescript", "java", "kotlin", "go", "ruby", "rust", "sql", "html", "css", "cpp", "csharp", "objective-c", "json", "xml", "yaml", "toml", "ini", "markdown", "bash", "zsh", "powershell", "standard", "plain"], id: \.self) { lang in Button(lang.capitalized) { if let tab = viewModel.selectedTab { viewModel.updateTabLanguage(tab: tab, language: lang) } } .disabled(viewModel.selectedTab == nil) } } CommandMenu("AI") { Button("API Settings…") { NotificationCenter.default.post(name: .showAPISettingsRequested, object: nil) } Divider() Button("Use Apple Intelligence") { NotificationCenter.default.post(name: .selectAIModelRequested, object: AIModel.appleIntelligence.rawValue) } Button("Use Grok") { NotificationCenter.default.post(name: .selectAIModelRequested, object: AIModel.grok.rawValue) } Button("Use OpenAI") { NotificationCenter.default.post(name: .selectAIModelRequested, object: AIModel.openAI.rawValue) } Button("Use Gemini") { NotificationCenter.default.post(name: .selectAIModelRequested, object: AIModel.gemini.rawValue) } Button("Use Anthropic") { NotificationCenter.default.post(name: .selectAIModelRequested, object: AIModel.anthropic.rawValue) } } CommandMenu("View") { Toggle("Toggle Sidebar", isOn: $viewModel.showSidebar) .keyboardShortcut("s", modifiers: [.command, .option]) Button("Toggle Project Structure Sidebar") { NotificationCenter.default.post(name: .toggleProjectStructureSidebarRequested, object: nil) } Toggle("Brain Dump Mode", isOn: $viewModel.isBrainDumpMode) .keyboardShortcut("d", modifiers: [.command, .shift]) Toggle("Line Wrap", isOn: $viewModel.isLineWrapEnabled) .keyboardShortcut("l", modifiers: [.command, .option]) Button("Toggle Translucent Window Background") { NotificationCenter.default.post(name: .toggleTranslucencyRequested, object: !enableTranslucentWindow) } } CommandMenu("Editor") { Button("Clear Editor") { NotificationCenter.default.post(name: .clearEditorRequested, object: nil) } Button("Toggle Code Completion") { NotificationCenter.default.post(name: .toggleCodeCompletionRequested, object: nil) } Button("Find & Replace") { NotificationCenter.default.post(name: .showFindReplaceRequested, object: nil) } .keyboardShortcut("f", modifiers: .command) } CommandMenu("Tools") { Button("Suggest Code") { Task { if let tab = viewModel.selectedTab { let contentPrefix = String(tab.content.prefix(1000)) let prompt = "Suggest improvements for this \(tab.language) code: \(contentPrefix)" let grokToken = UserDefaults.standard.string(forKey: "GrokAPIToken") ?? "" let openAIToken = UserDefaults.standard.string(forKey: "OpenAIAPIToken") ?? "" let geminiToken = UserDefaults.standard.string(forKey: "GeminiAPIToken") ?? "" let client: AIClient? = { #if USE_FOUNDATION_MODELS if useAppleIntelligence { return AIClientFactory.makeClient(for: AIModel.appleIntelligence) } #endif if !grokToken.isEmpty { return AIClientFactory.makeClient(for: .grok, grokAPITokenProvider: { grokToken }) } if !openAIToken.isEmpty { return AIClientFactory.makeClient(for: .openAI, openAIKeyProvider: { openAIToken }) } if !geminiToken.isEmpty { return AIClientFactory.makeClient(for: .gemini, geminiKeyProvider: { geminiToken }) } #if USE_FOUNDATION_MODELS return AIClientFactory.makeClient(for: .appleIntelligence) #else return nil #endif }() guard let client else { grokErrorMessage = "No AI provider configured."; showGrokError = true; return } var aggregated = "" for await chunk in client.streamSuggestions(prompt: prompt) { aggregated += chunk } viewModel.updateTabContent(tab: tab, content: tab.content + "\n\n// AI Suggestion:\n" + aggregated) } } } .keyboardShortcut("g", modifiers: [.command, .shift]) .disabled(viewModel.selectedTab == nil) Toggle("Use Apple Intelligence", isOn: $useAppleIntelligence) } CommandMenu("Diagnostics") { Text(appleAIStatus) Divider() Button("Re-run Apple Intelligence Health Check") { Task { #if USE_FOUNDATION_MODELS do { let start = Date() _ = try await AppleFM.appleFMHealthCheck() let end = Date() appleAIStatus = "Apple Intelligence: Ready" appleAIRoundTripMS = end.timeIntervalSince(start) * 1000.0 } catch { appleAIStatus = "Apple Intelligence: Error — \(error.localizedDescription)" appleAIRoundTripMS = nil } #else appleAIStatus = "Apple Intelligence: Unavailable (build without USE_FOUNDATION_MODELS)" appleAIRoundTripMS = nil #endif } } if let ms = appleAIRoundTripMS { Text(String(format: "Last round-trip: %.1f ms", ms)) .foregroundStyle(.secondary) } } } #else WindowGroup { ContentView() .environmentObject(viewModel) .environment(\.showGrokError, $showGrokError) .environment(\.grokErrorMessage, $grokErrorMessage) } #endif } } struct ShowGrokErrorKey: EnvironmentKey { static let defaultValue: Binding = .constant(false) } struct GrokErrorMessageKey: EnvironmentKey { static let defaultValue: Binding = .constant("") } extension EnvironmentValues { var showGrokError: Binding { get { self[ShowGrokErrorKey.self] } set { self[ShowGrokErrorKey.self] = newValue } } var grokErrorMessage: Binding { get { self[GrokErrorMessageKey.self] } set { self[GrokErrorMessageKey.self] = newValue } } }