Coming from Hazel
How Hazel's folders, rules, conditions and actions map to Switchboard, and what the import keeps, notes or leaves out.
Hazel watches folders and runs rules on the files that appear in them. Switchboard does the same with a File or folder change and the file steps. Import turns a Hazel export into one macro per watched folder, so the rules read the way they did in Hazel.
In Hazel, right-click a watched folder and choose Export Rules. Then choose File › Import… in Switchboard and pick the .hazelrules file (or switchboard import --hazel file.hazelrules). When Hazel's own folder holds .hazelrules files, Hazel rules on this Mac reads those.
Pause Hazel first #
Two engines acting on one folder move each other's files. Everything comes in off. In the review, tick Hazel is paused on these folders once you have paused Hazel (Hazel's menu, Pause, or remove the folder in its Folders list); the folders that can run then come in on.
Hazel runs its rules on what is already in a folder when you add it. Tick Run on each folder's contents when it's turned on to do the same once: the folder's trigger then catches up on the files already there.
How a folder reads #
One folder is one group and one macro, Rules for Downloads. The trigger is a file trigger on the folder (its own files only unless Hazel included subfolders), waiting for a file to stop changing before it runs. Each rule is an If step named after the rule, in Hazel's order, with the rule's conditions and actions inside:
WHEN a file appears in Downloads
DO If PDF invoice → tag, sort into Invoices/2026/10, stop
If screenshot → rename, move, stop
…
As in Hazel, the first rule a file matches runs and ends the run. A rule that continues (Hazel's Continue matching rules) simply doesn't stop. Ignore file is a rule that stops and does nothing. A rule switched off in Hazel comes in switched off. The trace names the rule that matched.
Conditions #
| Hazel | Switchboard | Note |
|---|---|---|
| Name, Extension, Full name | fileAttribute BaseName, Extension, Name | Text comparisons ignore case |
| Kind (PDF, Image, Movie, …) | ContentType conforms to a type | A kind with no type is compared with the Finder's kind text, with a note |
| Date added, created, modified, last opened | AddedDate, CreationDate, ModificationDate, LastUsedDate | Before, after, in the last and not in the last N days |
| Date last matched | LastMatched and a file.remember step | The rule records the files it handled in shared.hazel.<folder>.<rule>; entries older than 90 days drop |
| Size | Size | KB, MB and GB are counted in thousands, as the Finder does |
| Tags, Color label | Tags, ColorLabel | |
| Source URL / address | WhereFrom | |
| Contents | Contents | Spotlight's text, else the file's own text up to 2 MB |
| Subfolder depth | Depth from the folder | |
| Current time | A time condition | A range such as 09:00-17:00 |
| Passed all rules | Nothing | The rules above already stopped the file if they matched |
| Is, is not, contains, starts with, ends with, matches | eq, ne, contains, startsWith, endsWith, matches (a regular expression) | The "does not" forms are negate |
| Any, All, None of the following | The If step's match | None negates each condition. A group inside All becomes an If inside the rule; a group inside Any is flattened, with a note |
A condition Switchboard can't test switches its rule off, with a note, so the rule can't fire wrongly.
Actions #
| Hazel | Switchboard | Note |
|---|---|---|
| Move, Copy | Move or sort a file, Copy a file to a folder | If the name is taken: a number is added (name 2.ext), unless Hazel said replace or skip |
| Sort into subfolder | file.move with a subfolder | The subfolder pattern uses the same tokens |
| Rename | Rename a file from a pattern | Hazel's name tokens become {name}, {ext}, {added:yyyy-MM-dd}, {counter:3} |
| Custom attributes from a pattern match | {{match(file.stem, "regex", n)}} | The n-th group of the condition's expression |
| Add tags, Set color label, Add comment | Add Finder tags to a file, Set a file's color label, Set a file's Finder comment | |
| Open, Open with, Show in Finder | openFile with an app, Show a file in the Finder | |
| Archive, Unarchive | Zip a file or folder, Unzip an archive | |
| Move to Trash, Delete | Move a file to the Trash | Delete moves to the Trash, with a note: Hazel removed the file for good |
| Run AppleScript, JavaScript, shell script | appleScript, jxa, shell | The file is passed as hazelProcessFile's argument, or as $1 |
| Display notification, Speak, Play sound | notify, speak, shell | |
| Import into Photos or Music | A shell step with osascript | With a note; macOS asks permission the first time |
| Upload (FTP, SFTP, WebDAV) | A shell step with curl | Logins are never imported |
| Sync | Copy a file to a folder | A one-way copy made once, with a note |
| Continue matching rules, Ignore file | The rule doesn't stop, or stops and does nothing |
Name tokens and the counter #
Names and folders are templates. {{ }} works as everywhere ({{file.name}}, {{file.ext}}, {{file.path}}), and the file steps fill in {name}, {ext}, {fullname}, {parent}, {added:…}, {created:…}, {modified:…}, {opened:…}, {now:…} and {counter:3}. The counter goes up by one each time the step runs and is kept across restarts, per rule and folder, so a file trigger that runs one file at a time never repeats a number.
Trash options #
Hazel's "delete after N days" and "items larger than N MB" become macros in Hazel: Housekeeping that run at 03:00. They delete from the Trash for good, so they always come in off; reading the Trash needs Full Disk Access for the Switchboard engine.
What it can't do #
App Sweep (cleaning up after uninstalled apps) is not a folder rule and is not imported.
Logins for uploads are never imported.
Rules that Hazel stores outside the export, such as its own per-folder throttling, are not read.
This guide follows the export format as documented in the plan; if a rule reads wrong, send the export so the importer can be checked against it.