- 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>
63 lines
2.1 KiB
Swift
63 lines
2.1 KiB
Swift
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.")
|
|
}
|
|
}
|