app.system - System Information API

Retrieve system, hardware, and environment information.

Basic Info

app.system.osName()

Get the operating system name.

Returns: string - Always returns “macOS”

local os = app.system.osName()  -- "macOS"

app.system.osVersion()

Get the operating system version.

Returns: string - Version number

local version = app.system.osVersion()  -- "14.1.0"

app.system.osBuild()

Get the system build number.

Returns: string - Build number

local build = app.system.osBuild()  -- "23B74"

app.system.hostName()

Get the host name.

Returns: string - Host name

local host = app.system.hostName()  -- "MacBook-Pro.local"

app.system.userName()

Get the current user name.

Returns: string - User name

local user = app.system.userName()  -- "username"

app.system.fullUserName()

Get the full user name.

Returns: string - Full name

local name = app.system.fullUserName()  -- "John Doe"

Environment Variables

app.system.env(name)

Get an environment variable.

Parameters:

  • name (string) - Variable name

Returns: string|nil - Variable value or nil

local home = app.system.env("HOME")        -- "/Users/username"
local path = app.system.env("PATH")        -- "/usr/local/bin:..."
local custom = app.system.env("MY_VAR")    -- nil (if not set)

app.system.envAll()

Get all environment variables.

Returns: table - Key-value pairs

local env = app.system.envAll()
for name, value in pairs(env) do
    app.log.info(name .. " = " .. value)
end

app.system.setEnv(name, value)

Set an environment variable (only effective in the current process).

Parameters:

  • name (string) - Variable name
  • value (string) - Variable value

Returns: boolean - Whether successful

app.system.setEnv("MY_VAR", "my_value")

Hardware Info

app.system.arch()

Get CPU architecture.

Returns: string - “arm64” or “x86_64”

local arch = app.system.arch()  -- "arm64"

if arch == "arm64" then
    app.log.info("Apple Silicon Mac")
else
    app.log.info("Intel Mac")
end

app.system.cpuCount()

Get CPU core count.

Returns: number - Number of cores

local cores = app.system.cpuCount()  -- 8

app.system.memory()

Get memory information.

Returns: table

  • total (number) - Total memory (bytes)
  • available (number) - Available memory (bytes)
  • used (number) - Used memory (bytes)
local mem = app.system.memory()
app.log.info("Total memory: " .. (mem.total / 1024 / 1024 / 1024) .. " GB")
app.log.info("Available: " .. (mem.available / 1024 / 1024 / 1024) .. " GB")

app.system.diskSpace(path?)

Get disk space information.

Parameters:

  • path (string, optional) - Disk path (default “/”)

Returns: table|nil

  • total (number) - Total space (bytes)
  • available (number) - Available space (bytes)
  • used (number) - Used space (bytes)
local disk = app.system.diskSpace("/")
app.log.info("Available space: " .. (disk.available / 1024 / 1024 / 1024) .. " GB")

-- Check an external drive
local external = app.system.diskSpace("/Volumes/MyDrive")

app.system.deviceModel()

Get the device model identifier (since 1.3.0).

Returns: string - e.g. "MacBookPro18,3", "Macmini9,1"

local model = app.system.deviceModel()
app.log.info("Device model: " .. model)

Hardware Identifiers (PII)

The following APIs return personally identifiable information that can uniquely identify a device. Plugins must declare the hardware_id permission in plugin.json; a consent dialog will appear on first use.

app.system.serialNumber()

Get the Mac serial number (since 1.3.0, requires hardware_id permission).

Returns: string|nil, err - e.g. "C02XXXXXXXXX"

-- plugin.json: "permissions": ["system", "hardware_id"]
local sn, err = app.system.serialNumber()

app.system.hardwareUUID()

Get the hardware UUID (since 1.3.0, requires hardware_id permission).

Returns: string|nil, err - UUID format string

local uuid, err = app.system.hardwareUUID()

app.system.diskSerial(path?)

Get the disk serial/UUID for a volume (since 1.3.0, requires hardware_id permission).

Parameters:

  • path (string, optional) - Disk path (default /)

Returns: string|nil, err - Disk UUID or device path

local sn, err = app.system.diskSerial("/")

Login Item (1.3.0)

Manage iRightMenu Pro’s own login-at-startup state. Writing requires the login_item permission; reading does not.

app.system.isLoginItem()

Check whether iRightMenu Pro is set to launch at login (since 1.3.0).

Returns: boolean

if app.system.isLoginItem() then
    app.log.info("launch at login is enabled")
end

app.system.setLoginItem(enable)

Toggle iRightMenu Pro’s launch-at-login state (since 1.3.0, requires login_item permission, prompts on first use).

Parameters:

  • enable (boolean) - true to enable, false to disable

Returns: boolean, err

-- plugin.json: "permissions": ["system", "login_item"]
local ok, err = app.system.setLoginItem(true)

Language and Region

app.system.locale()

Get the system locale setting.

Returns: string - Locale code

local locale = app.system.locale()  -- "zh_CN"

app.system.language()

Get the system preferred language.

Returns: string - Language code

local lang = app.system.language()  -- "zh-Hans"

app.system.timezone()

Get the timezone.

Returns: string - Timezone identifier

local tz = app.system.timezone()  -- "Asia/Shanghai"

Other

app.system.uptime()

Get system uptime.

Returns: number - Seconds

local uptime = app.system.uptime()
local hours = math.floor(uptime / 3600)
app.log.info("System has been running for " .. hours .. " hours")

app.system.uuid()

Generate a new UUID.

Returns: string - UUID string

local id = app.system.uuid()  -- "A1B2C3D4-E5F6-..."

app.system.timestamp()

Get the current Unix timestamp.

Returns: number - Timestamp (seconds, with fractional part)

local ts = app.system.timestamp()  -- 1701234567.123

Directory Paths

For directory paths, use the app.path module:

app.path.home()         -- "/Users/username"
app.path.temp()         -- "/var/folders/.../T"
app.path.desktop()      -- "/Users/username/Desktop"
app.path.documents()    -- "/Users/username/Documents"
app.path.downloads()    -- "/Users/username/Downloads"
app.path.applications() -- "/Applications"

Event Watching

app.system.watch(event, callback)

Watch for system-level events.

Parameters:

  • event (string) - event name:
    • "sleep" - fired when the system is about to sleep
    • "wake" - fired when the system wakes from sleep
    • "screenLocked" - fired when the screen locks
    • "screenUnlocked" - fired when the screen unlocks
    • "volumeMount" - fired when a volume is mounted, callback receives: {type, path, name}
    • "volumeUnmount" - fired when a volume is unmounted, callback receives: {type, path, name}
  • callback (function) - callback function. sleep/wake/screenLocked/screenUnlocked receive no arguments; volumeMount/volumeUnmount receive:
    • type (string) - event type
    • path (string) - mount path (e.g. “/Volumes/MyDisk”)
    • name (string) - volume name

Returns: string, error - watcher handle ID

app.system.watch("sleep", function()
    app.log.info("System is going to sleep")
end)

app.system.watch("wake", function()
    app.log.info("System woke up")
end)

app.system.watch("volumeMount", function(e)
    app.notification.show("Volume Mounted", e.name .. " (" .. e.path .. ")")
end)

app.system.watch("volumeUnmount", function(e)
    app.log.info("Volume unmounted: " .. e.name)
end)

app.system.stopAllWatchers()

Stop all system event watchers registered by the current plugin.

Returns: boolean

app.system.stopAllWatchers()

app.system.listWatchers()

List all system event watchers registered by the current plugin.

Returns: array<table> - each item contains:

  • id (string) - watcher handle ID
  • event (string) - event name being watched
local watchers = app.system.listWatchers()
for _, w in ipairs(watchers) do
    app.log.info(w.id .. " -> " .. w.event)
end

Examples

Check System Requirements

function MyPlugin:checkRequirements()
    -- Check macOS version
    local version = app.system.osVersion()
    local major = tonumber(version:match("^(%d+)"))

    if major < 12 then
        app.dialog.alert({
            title = "Not Supported",
            message = "Requires macOS 12 or later"
        })
        return false
    end

    -- Check architecture
    if app.system.arch() ~= "arm64" then
        app.log.warning("Running on Intel Mac, performance may be reduced")
    end

    -- Check disk space
    local disk = app.system.diskSpace("/")
    local freeGB = disk.available / 1024 / 1024 / 1024

    if freeGB < 1 then
        app.dialog.alert({
            title = "Insufficient Space",
            message = "At least 1GB of free space is required"
        })
        return false
    end

    return true
end

Generate System Report

function MyPlugin:handleSystemInfo(context)
    local mem = app.system.memory()
    local disk = app.system.diskSpace("/")

    local info = {
        "System Information Report",
        "================",
        "",
        "OS: " .. app.system.osName() .. " " .. app.system.osVersion(),
        "Build: " .. app.system.osBuild(),
        "Architecture: " .. app.system.arch(),
        "Hostname: " .. app.system.hostName(),
        "User: " .. app.system.fullUserName() .. " (" .. app.system.userName() .. ")",
        "",
        "CPU Cores: " .. app.system.cpuCount(),
        "Memory: " .. string.format("%.1f GB", mem.total / 1024^3),
        "Available Memory: " .. string.format("%.1f GB", mem.available / 1024^3),
        "",
        "Disk Total: " .. string.format("%.1f GB", disk.total / 1024^3),
        "Disk Available: " .. string.format("%.1f GB", disk.available / 1024^3),
        "",
        "Language: " .. app.system.language(),
        "Locale: " .. app.system.locale(),
        "Timezone: " .. app.system.timezone(),
        "",
        "Uptime: " .. string.format("%.1f hours", app.system.uptime() / 3600),
        "",
        "Generated at: " .. os.date("%Y-%m-%d %H:%M:%S")
    }

    local report = table.concat(info, "\n")

    -- Save the report
    local path = app.path.join(context.currentDirectory, "system_info.txt")
    app.file.write(path, report)

    app.finder.reveal(path)
end

Adjust Behavior Based on System Configuration

function MyPlugin:getOptimalThreadCount()
    local cores = app.system.cpuCount()

    -- Reserve some cores for the system
    local threads = math.max(1, cores - 2)

    -- Check available memory
    local mem = app.system.memory()
    local freeGB = mem.available / 1024 / 1024 / 1024

    -- Reduce threads if memory is low
    if freeGB < 2 then
        threads = math.min(threads, 2)
    end

    return threads
end
Developer Documentation
User Guide
Getting Started Script Menus FAQ
Script Development
Development Guide
Plugin Development
Quick Start Development Guide Example Plugins
API Reference
Overview API Query Plugin Info Logging Finder Context Plugin Settings Internationalization
UI & Interaction
Dialog Progress Notification Chooser WebView Status Bar Dock
Files & Paths
File Operations Path Utilities Finder Actions Trash Extended Attributes Metadata File Watcher
Data Formats
JSON Plist CSV XML PDF Image
Text & Encoding
String Regex Date & Time Color Crypto
System
Shell Commands Process Application System Info AppleScript Shortcuts
System Info
Network Power/Battery Screen/Appearance Audio Bluetooth Location
Network
HTTP WebSocket URL
Input & Clipboard
Keyboard Mouse Hotkey Clipboard Window
Storage
SQLite Keychain UserDefaults
Media
OCR QR Code
Utilities
Archive UTI Share Timer Wake Lock Thread