{
  "format" : 1,
  "manifest" : {
    "accent" : "graphite",
    "capabilities" : [
      {
        "systemActions" : {

        }
      }
    ],
    "homepage" : "https://github.com/navbytes/stackbar-plugins/tree/main/System/SystemCommands",
    "id" : "io.navbytes.stackbar.plugins.system-commands",
    "minimumStackbar" : "0.35.0",
    "name" : "System Commands",
    "summary" : "Lock, sleep, restart, empty the Trash or switch to dark mode from the palette.",
    "surfaces" : [
      "panel"
    ],
    "symbol" : "power.circle.fill",
    "triggers" : [
      {
        "launch" : {

        }
      }
    ],
    "version" : "1.1.0"
  },
  "publisher" : {
    "name" : "navbytes",
    "publicKey" : "4dpLtXEpFXdi+6cviY/KdYuUulJPbEmCxxIK0EEN2/w="
  },
  "signature" : "ceVkFmRkWqiX0sxFTWeuR0nVBJO4oR+ezpvhDgGVW4JtlRfGylTPInJaski8Ptz2T37wcZj4cJD1brgXKTjDAQ==",
  "source" : "import StackbarKit\nimport Foundation\n\n/// Lock, sleep, restart and the rest, by name in the palette, as Raycast's\n/// and Alfred's system commands are: type `lock`, `sleep`, `empty trash` or\n/// `dark mode` and press Return. Restart, shut down, log out, emptying the\n/// Trash and quitting other apps ask once more before they run.\n@main\nfinal class SystemCommands: StackbarPlugin {\n    static let manifest = Manifest(\n        id: \"io.navbytes.stackbar.plugins.system-commands\",\n        name: \"System Commands\",\n        version: \"1.1.0\",\n        summary: \"Lock, sleep, restart, empty the Trash or switch to dark mode from the palette.\",\n        surfaces: [.panel],\n        triggers: [.launch],\n        capabilities: [.systemActions],\n        minimumStackbar: \"0.35.0\",\n        homepage: \"https://github.com/navbytes/stackbar-plugins/tree/main/System/SystemCommands\",\n        accent: .graphite,\n        symbol: \"power.circle.fill\"\n    )\n\n    // MARK: Previews\n\n    static let previews: [PreviewScene<SystemCommands>] = [\n        PreviewScene(\"hero\", \"Lock, sleep or switch to dark mode by name\") { _ in },\n    ]\n\n    let theme = Theme.graphite\n\n    /// The commands, in the order the panel lists them.\n    struct Item: Sendable {\n        var action: SystemAction\n        var id: String\n        var symbol: String\n        var subtitle: String\n        var keywords: [String]\n        /// What the HUD says after it ran, for the actions that leave you\n        /// at the screen.\n        var done: String?\n    }\n\n    static let items: [Item] = [\n        Item(action: .lockScreen, id: \"lock-screen\", symbol: \"lock.fill\", subtitle: \"Lock the Mac now\", keywords: [\"lock\", \"away\"], done: nil),\n        Item(action: .sleep, id: \"sleep\", symbol: \"moon.zzz.fill\", subtitle: \"Put the Mac to sleep\", keywords: [\"sleep\", \"suspend\"], done: nil),\n        Item(action: .sleepDisplays, id: \"sleep-displays\", symbol: \"display\", subtitle: \"Turn the screens off\", keywords: [\"display\", \"screen\", \"monitor\", \"off\"], done: nil),\n        Item(action: .startScreenSaver, id: \"screen-saver\", symbol: \"sparkles.tv\", subtitle: \"Start the screen saver\", keywords: [\"screensaver\"], done: nil),\n        Item(action: .toggleDarkMode, id: \"toggle-dark-mode\", symbol: \"circle.lefthalf.filled\", subtitle: \"Switch between light and dark\", keywords: [\"dark\", \"light\", \"appearance\", \"theme\"], done: \"Appearance switched\"),\n        Item(action: .hideOtherApps, id: \"hide-other-apps\", symbol: \"eye.slash\", subtitle: \"Hide every app but the one you're in\", keywords: [\"hide\", \"focus\"], done: \"Other apps hidden\"),\n        Item(action: .ejectDisks, id: \"eject-disks\", symbol: \"eject.fill\", subtitle: \"Eject every external disk and disk image\", keywords: [\"eject\", \"unmount\", \"usb\", \"disk\"], done: \"Disks ejected\"),\n        Item(action: .emptyTrash, id: \"empty-trash\", symbol: \"trash.fill\", subtitle: \"Delete what's in the Trash for good\", keywords: [\"trash\", \"bin\", \"delete\"], done: \"Trash emptied\"),\n        Item(action: .quitOtherApps, id: \"quit-other-apps\", symbol: \"xmark.app.fill\", subtitle: \"Quit every app but Finder and the one you're in\", keywords: [\"quit\", \"close\", \"all\"], done: \"Other apps quitting\"),\n        Item(action: .logOut, id: \"log-out\", symbol: \"rectangle.portrait.and.arrow.right\", subtitle: \"Log out of this Mac\", keywords: [\"logout\", \"sign out\"], done: nil),\n        Item(action: .restart, id: \"restart\", symbol: \"arrow.clockwise.circle.fill\", subtitle: \"Restart the Mac\", keywords: [\"reboot\"], done: nil),\n        Item(action: .shutDown, id: \"shut-down\", symbol: \"power\", subtitle: \"Turn the Mac off\", keywords: [\"shutdown\", \"power off\", \"turn off\"], done: nil),\n    ]\n\n    func perform(_ item: Item) async throws {\n        try await Stackbar.system(item.action)\n        if let done = item.done { Stackbar.hud(done) }\n    }\n\n    /// Runs it and says why when it can't: a click's error otherwise only reaches the log.\n    func run(_ item: Item) async {\n        do { try await perform(item) } catch { Stackbar.hud(\"\\(error)\", isError: true) }\n    }\n\n    // MARK: Commands\n\n    var commands: [Command] {\n        return Self.items.map { item in\n            if item.action.isDestructive {\n                // A second Return, on a row that says what happens, before\n                // anything is lost.\n                return Command(item.id, title: item.action.title, subtitle: item.subtitle, symbol: item.symbol, keywords: item.keywords)\n                    .view { _ in\n                        List {\n                            Row(\"\\(item.action.title) Now\", subtitle: item.subtitle, symbol: item.symbol, key: \"confirm\")\n                                .action(item.action.title, role: .critical, confirm: .none) { await self.run(item) }\n                        }\n                    }\n            }\n            return Command(item.id, title: item.action.title, subtitle: item.subtitle, symbol: item.symbol, keywords: item.keywords) { _ in\n                try await Stackbar.system(item.action)\n                return .message(item.done)\n            }\n        }\n    }\n\n    // MARK: Panel\n\n    var panel: ViewContent {\n        PanelHeader(\"System Commands\", subtitle: \"Type any of these in the palette\", symbol: \"power.circle.fill\", theme: theme)\n        Card(\"Now\", spacing: 0, padding: Space.s) {\n            ForEach(Self.items.filter { !$0.action.isDestructive }) { item in\n                Row(item.action.title, subtitle: item.subtitle, symbol: item.symbol, key: item.id)\n                    .action(item.action.title) { await self.run(item) }\n            }\n        }\n        Card(\"Asks first\", spacing: 0, padding: Space.s) {\n            ForEach(Self.items.filter(\\.action.isDestructive)) { item in\n                // Stackbar asks for a second click before it runs.\n                Row(item.action.title, subtitle: item.subtitle, symbol: item.symbol, key: item.id)\n                    .action(item.action.title, role: .critical, confirm: Confirm(item.subtitle.prefix(1).lowercased() + item.subtitle.dropFirst())) { await self.run(item) }\n            }\n        }\n    }\n}\n",
  "sourceDigest" : "564890572141d1a4128312ff7dc2320174714f9bfa960ff670c9df8de093ba61"
}