import Foundation /// Subset of colors.toml that the Swift shell actually uses. struct LayersColors { var alphaFocusedHovered: CGFloat = 1.0 var alphaPartial: CGFloat = 0.5 var alphaIdle: CGFloat = 0.1 /// Locate the plugin root containing `resources/colors.toml`. /// The Layers.app bundle lives at `/bin/Layers.app`, so climb two levels. static func pluginRoot() -> String { let appPath = Bundle.main.bundlePath as NSString let binDir = appPath.deletingLastPathComponent as NSString return binDir.deletingLastPathComponent } static func load() -> LayersColors { var result = LayersColors() let path = (pluginRoot() as NSString) .appendingPathComponent("resources") .appending("/colors.toml") guard let src = try? String(contentsOfFile: path, encoding: .utf8) else { return result } let flat = flatten(src) if let v = flat["window.alpha_focused_hovered"] as Double? { result.alphaFocusedHovered = CGFloat(v) } if let v = flat["window.alpha_partial"] as Double? { result.alphaPartial = CGFloat(v) } if let v = flat["window.alpha_idle"] as Double? { result.alphaIdle = CGFloat(v) } return result } /// Minimal key=value extractor for the flat subset we care about. /// Returns dotted "section.key" → numeric value. private static func flatten(_ source: String) -> [String: Double] { var out: [String: Double] = [:] var section = "" for rawLine in source.split(separator: "\n", omittingEmptySubsequences: false) { let line = String(rawLine).trimmingCharacters(in: .whitespaces) if line.isEmpty || line.hasPrefix("#") { continue } if line.hasPrefix("[") && line.hasSuffix("]") { section = String(line.dropFirst().dropLast()).trimmingCharacters(in: .whitespaces) continue } guard let eq = line.firstIndex(of: "=") else { continue } let key = line[..