Add macOS menu bar app with chat and settings
- Restructure project into three targets: - AppleIntelligenceCore: Shared gRPC service code - AppleIntelligenceServer: CLI server - AppleIntelligenceApp: Menu bar app - Menu bar app features: - Toggle server on/off from menu bar - Chat window with streaming AI responses - Settings: host, port, API key, auto-start, launch at login - Proper window focus handling for menu bar apps - Add build scripts for distribution: - build-app.sh: Creates signed .app bundle - create-dmg.sh: Creates distributable DMG 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
import Foundation
|
||||
import GRPCCore
|
||||
import GRPCNIOTransportHTTP2
|
||||
import ArgumentParser
|
||||
import AppleIntelligenceCore
|
||||
|
||||
@main
|
||||
struct AppleIntelligenceServer: AsyncParsableCommand {
|
||||
static let configuration = CommandConfiguration(
|
||||
abstract: "Apple Intelligence gRPC Server",
|
||||
discussion: "Exposes Apple Intelligence (Foundation Models) over gRPC for LAN access."
|
||||
)
|
||||
|
||||
@Option(name: .shortAndLong, help: "Host to bind to")
|
||||
var host: String?
|
||||
|
||||
@Option(name: .shortAndLong, help: "Port to listen on")
|
||||
var port: Int?
|
||||
|
||||
func run() async throws {
|
||||
let config = Config()
|
||||
let bindHost = host ?? config.host
|
||||
let bindPort = port ?? config.port
|
||||
|
||||
print("Initializing Apple Intelligence service...")
|
||||
let service = await AppleIntelligenceService()
|
||||
|
||||
let modelStatus = await service.getModelStatus()
|
||||
print("Model status: \(modelStatus)")
|
||||
|
||||
guard await service.isAvailable else {
|
||||
print("Error: Apple Intelligence is not available on this device.")
|
||||
print("Please ensure:")
|
||||
print(" - You are running macOS 26 (Tahoe) or later")
|
||||
print(" - You have an Apple Silicon Mac")
|
||||
print(" - Apple Intelligence is enabled in System Settings")
|
||||
throw ExitCode.failure
|
||||
}
|
||||
|
||||
let provider = AppleIntelligenceProvider(service: service, apiKey: config.apiKey)
|
||||
|
||||
let transport = HTTP2ServerTransport.Posix(
|
||||
address: .ipv4(host: bindHost, port: bindPort),
|
||||
transportSecurity: .plaintext,
|
||||
config: .defaults
|
||||
)
|
||||
|
||||
let server = GRPCServer(transport: transport, services: [provider])
|
||||
|
||||
print("Starting gRPC server on \(bindHost):\(bindPort)...")
|
||||
if config.apiKey != nil {
|
||||
print("API key authentication is enabled")
|
||||
}
|
||||
print("Server is ready to accept connections")
|
||||
print("Health check: grpcurl -plaintext \(bindHost):\(bindPort) appleintelligence.AppleIntelligence/Health")
|
||||
print("Press Ctrl+C to stop the server")
|
||||
|
||||
try await server.serve()
|
||||
|
||||
print("Server stopped.")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user