Recipes

Disk usage

Circular gauge for the boot volume with color flip at 90%, used/free/total breakdown in the popover.

Demonstrates a circular gauge driven by a numeric binding, color flip via if, and ${path:%.1f} format specs.

yaml
id: disk
interval: 60
order: 55
location: tray
click:
    shell: "open '/'"
command: |
    df -k / | awk 'NR==2 {
      used   = $3
      avail  = $4
      total  = used + avail
      pct    = (total > 0) ? used * 100 / total : 0
      printf "{\"used_gb\":%.1f,\"avail_gb\":%.1f,\"total_gb\":%.1f,\"pct\":%.0f}\n",
             used/1024/1024, avail/1024/1024, total/1024/1024, pct
    }'
view:
    hstack:
      spacing: 4
      children:
        - if:
            when: "${pct} >= 90"
            then:
              gauge: { value: "${pct}", min: 0, max: 100, tint: "#FF3B30", style: circular, width: 16, height: 16 }
            else:
              gauge: { value: "${pct}", min: 0, max: 100, tint: "#5AC8FA", style: circular, width: 16, height: 16 }
        - text:
            content: "${pct}%"
            size: 10
            weight: medium
            design: rounded
            monospacedDigit: true
hover:
    vstack:
      spacing: 8
      alignment: leading
      frame: { width: 200 }
      children:
        - hstack:
            children:
              - text: { content: "Disk", size: 11, color: secondary, weight: medium }
              - spacer: {}
              - text: { content: "${pct}%", size: 18, weight: semibold, design: rounded, monospacedDigit: true }
        - gauge:
            value: "${pct}"
            min: 0
            max: 100
            tint: "#5AC8FA"
            width: 176
            height: 6
        - hstack:
            spacing: 16
            children:
              - vstack:
                  alignment: leading
                  spacing: 0
                  children:
                    - text: { content: "${used_gb:%.1f} GB", size: 12, weight: semibold, design: rounded }
                    - text: { content: "Used",  size: 9, color: secondary }
              - vstack:
                  alignment: leading
                  spacing: 0
                  children:
                    - text: { content: "${avail_gb:%.1f} GB", size: 12, weight: semibold, design: rounded }
                    - text: { content: "Free",  size: 9, color: secondary }
              - vstack:
                  alignment: leading
                  spacing: 0
                  children:
                    - text: { content: "${total_gb:%.1f} GB", size: 12, weight: semibold, design: rounded }
                    - text: { content: "Total", size: 9, color: secondary }
              - spacer: {}

What this teaches

  • Circular gauge — a 16×16 ring rendered from a single ${pct} binding, looks great in the bar.
  • Format specs in text${used_gb:%.1f} produces "16.5", append units in literal text (" GB").
  • Layout composition — three side-by-side stat columns inside an outer hstack, each its own vstack.

Building on this

  • Add a per-volume widget by changing df -k / to df -k /Volumes/Backup (or whatever your secondary volume is).
  • Watch a specific subdirectory by replacing df with du -sk <path> and dividing differently — useful for monitoring a Dropbox or Photos library size.
  • Trigger a notification when crossing 95% by wrapping the script in: pct=$(...); [ "$pct" -ge 95 ] && osascript -e 'display notification "Disk almost full"'.