Event-Driven Automation on macOS with Crank

Laptop displaying a connected software workflow with device icons, notifications, cloud services, and code panels

Remark: This arti­cle is a trans­la­tion of my Ger­man orig­i­nal, cre­at­ed with the help of AI. Eng­lish is not my first lan­guage, so some phras­es may sound unusu­al.

Crank is an app that runs in the back­ground and can per­form dif­fer­ent actions when some­thing hap­pens on your sys­tem. For exam­ple, Crank can react when head­phones con­nect via Blue­tooth or when a screen­shot lands in a fold­er. Crank’s job is to lis­ten for cer­tain events, which are defined as trig­gers, and then start an action. It works much like Short­ery, which, how­ev­er, can only run Apple Short­cuts as an action. In Crank, you can also use Short­cuts as an action, and in addi­tion scripts writ­ten in dif­fer­ent lan­guages.

I am inter­est­ed in automa­tion on macOS and in writ­ing scripts, so I found Crank’s approach inter­est­ing and want­ed to take a clos­er look. The devel­op­ment team The low-tech guys kind­ly gave me a copy of Crank for this review. The slo­gan “Effort­less macOS automa­tion – no man­u­al required” made me even more curi­ous.

Crank offers more than 30 trig­gers. They react to changes in the sys­tem, for exam­ple, join­ing a Wi-Fi net­work, con­nect­ing a USB device, new con­tent in the clip­board, or a change of Focus mode. In response, Crank can per­form the fol­low­ing actions:

  • Noti­fy: show a noti­fi­ca­tion
  • Open: launch an app, open a URL, open a file
  • Auto­mate: run a Short­cut, an Apple­Script, or a shell script (zsh, Python 3, Ruby, Perl, Swift, or a cus­tom inter­preter)
  • Con­trol Crank: acti­vate a pro­file, enable or dis­able a rule

At the time of this review, the app is a one-time pur­chase for €10.00 instead of the reg­u­lar price of €14.28. You can also try it free for 14 days. It requires macOS 14.0 (Sono­ma) or lat­er.

The User Interface

Picture Show the user Interface of crank. Will be explained in detail in the text

The UI is fair­ly self-explana­to­ry, although it does not ful­ly fol­low Apple’s con­ven­tions. The title bar con­tains sev­er­al func­tions. With the but­tons at (1), you can show and hide the trig­ger area on the left, open the set­tings (⌘,), open the com­mand palette (⌘K), and switch the dis­play of the rules (6) between the list view shown here and a table view.

With the switch­er at (2), you change between three views: the “Trig­ger” view, the Event Log (⌘2), and the “Action His­to­ry” (⌘3). The “Trig­ger” view is the main view. It con­sists of the trig­ger list (1) and the rules area (6), which shows the rules as a list of rule box­es. The Event Log shows all events that the sys­tem gen­er­ates and that Crank watch­es. The Action His­to­ry lists the actions that were exe­cut­ed, togeth­er with their out­put and any errors.

The but­ton at (3) is a menu and shows the name of the active pro­file. When you open it, you can man­age pro­files and cre­ate new ones, in which you can then cre­ate new rules. With pro­files, you can, for exam­ple, have a dif­fer­ent set of rules active at work than at home. Using the con­text menu (right-click) of a rule, you can move it to anoth­er pro­file.

Area (4) con­tains the func­tions of the tool­bar, shown here enlarged:

Image shows the upper rigth part of the Trigger Page Toolbars. There are numbers used in the text for expkaination
  1. Enable all rules
  2. Dis­able all rules
  3. Expand all groups
  4. Col­lapse all groups
  5. “DryRun”: Puts the whole sys­tem into a test mode. Crank still checks the con­di­tions of the rules and logs the result in the Action His­to­ry, but it does not exe­cute the actions.
  6. Undo the dele­tion of a rule
  7. Save all set­tings as a back­up (do not con­fuse this with the Share but­ton)
  8. Load a back­up

The Event Log

Image shows the event-log screen There are numbers used in the text for explanation.

The Event Log (2) gives you an overview of the events that Crank can react to when “All Trig­gers” is active at (1). For debug­ging, you can use “Enabled Rules Only” to lim­it the entries to events for which active rules exist.

In the drop­down menu (3), you can fil­ter the log by trig­ger area. The trash can (5) clears the log, and with the search field (6), you can look for a spe­cif­ic entry.

The Action History

Image shows the Activity History screen There are numbers used in the text for explanation.

The Action His­to­ry logs the actions that were exe­cut­ed. Each entry shows the time, the rule, the trig­ger that start­ed it, and the action. Runs that hap­pened in DryRun mode are marked with “DRY RUN”. If you expand an entry (3), you see the out­put of the script, the exit code with the run time, and the val­ues of the event that start­ed it.

The red text is not nec­es­sar­i­ly an error. Red is used for the stan­dard error out­put (stderr) of the script, and this also con­tains nor­mal sta­tus mes­sages, here for exam­ple the new name under which the screen­shot was saved. The exit code shows whether an action was suc­cess­ful. A 0 (green) means suc­cess, any­thing else (red) means an error. In this way, the script in the low­er entry was stopped after 30 sec­onds (“Script timed out after 30 sec­onds”, exit ‑1).

The warn­ing tri­an­gle (1) fil­ters the entries for actions that do not end with exit code 0, mean­ing they did not lead to the desired result. The trash can (1) clears the list, and with the search field (2), you can find indi­vid­ual entries.

How Rules Are Built

Image shows the how the trigger screen looks like with an rule screen There are numbers used in the text for explanation.

A rule always starts with a trig­ger, which you first select in the left side­bar (1). In this exam­ple, it is “File/Folder changes” → “cre­at­ed”. When you select it, the rule is cre­at­ed and the first line, “WHEN” (2), is added. It defines that the rule should react to events that report changes in the file sys­tem. Although the side­bar says “Files” here, the “File Watch­er” also reacts to fold­ers that are cre­at­ed, changed, or delet­ed.

In the next line, “IF” (3), you set a con­di­tion that nar­rows down which files or fold­ers to watch. In the exam­ple, the file name must con­tain the text “Bild­schirm” (the Ger­man pre­fix of screen­shot file names).

The “THEN” line (4) defines which action should be exe­cut­ed, for exam­ple a Short­cut, an Apple­Script, a script, or just a noti­fi­ca­tion. In the exam­ple, it is “Run Shell Script”. The time­out shown here (one minute in the exam­ple) is set below the script box (5).

In the fol­low­ing line (6), you set the loca­tion to be watched (“Watch Path”) and whether sub­fold­ers are includ­ed (“Recur­sive”).

If a script should be exe­cut­ed, as in this exam­ple, you can choose the inter­preter at (7). Besides zsh, Python 3, Ruby, Perl, and Swift, you can also spec­i­fy a cus­tom inter­preter.

You enter the script in the box (8). To the right of it (9), you find the vari­ables that you can use in the script, such as $fileName and $filePath. I will cov­er the but­ton at the bot­tom of the script box (“Gen­er­ate code”) fur­ther below.

Depend­ing on the inter­preter, addi­tion­al options appear. For a zsh script, the check­box “Load ~/.zshrc” (10) lets you decide whether the per­son­al con­fig­u­ra­tion file of the shell should also be loaded. With “Run” (10), you can exe­cute the script direct­ly. A Swift script can also be com­piled if you want. This prob­a­bly only makes sense when the script is fin­ished, but then it speeds up exe­cu­tion sig­nif­i­cant­ly.

Below the script box, there are set­tings that influ­ence how the script runs. The time­out (5) makes sure that a script that runs too long for any rea­son is stopped. This way, a hang­ing script can­not run for­ev­er. If the time­out is exceed­ed, the Action His­to­ry shows “Script timed out” with exit code ‑1, as in the exam­ple above.

Below that are the set­tings “Rate Lim­it”, “Sched­ule”, and “Con­di­tions” (11). In the “Rate Lim­it” drop­down menu, you can define how the rule should behave when an event is trig­gered sev­er­al times in quick suc­ces­sion. One exam­ple is clos­ing a Mac­Book. This trig­gers the “LidAn­gle” event, which can repeat many times. With the “Throt­tle” option, the action is exe­cut­ed at the first occur­rence, and all fur­ther events are ignored for a defined time win­dow. With “Debounce”, on the oth­er hand, the rule waits for a defined time before it exe­cutes the action. For “LidAn­gle”, “Debounce” seems more use­ful to me, because the action is only exe­cut­ed after the wait­ing time and not already at the first change of the angle. (I have not tried this.)

With the “Sched­ule” option, you can define on which days of the week and in which time win­dow the rule should be active. Under the “Con­di­tions” switch, you can also define addi­tion­al con­di­tions that belong to the trig­ger. If the File Watch­er looks for a spe­cif­ic file name (3) in a spe­cif­ic fold­er (6), as in the exam­ple, you can also set here that only changes to fold­ers, not to files, are con­sid­ered. This means the con­di­tions are spread over three places: the file name in the IF line (3), the loca­tion in “Watch Path” (6), and fur­ther ones under “Con­di­tions”. I do not under­stand why they are not com­bined in one place.

With the last option (12), “Also run an action when the file is delet­ed”, you can addi­tion­al­ly define an action for the oppo­site event, here the dele­tion of the file. When you turn on the switch, a sec­ond “WHEN” line with the oppo­site trig­ger (“file delet­ed”) appears in the upper part of the rule, and you can define a sep­a­rate action for it (see image). Here, too, I do not under­stand why the switch is placed at the bot­tom of the rule and not where the def­i­n­i­tion hap­pens after­ward.

Image shows the consition part of a rule.

Creating Rules and Scripts with AI

Cre­at­ing a rule is quite easy. First you choose the right trig­ger, then you set the con­di­tion, and final­ly you choose an action. Sim­ple actions, such as a noti­fi­ca­tion when the bat­tery lev­el drops below a cer­tain val­ue, or open­ing a URL when the com­put­er starts, can be put togeth­er quick­ly with a few clicks. When the action becomes more com­plex, it takes more effort. The eas­i­est way may then be an Apple Short­cut as the action, because with macOS 27, Apple sup­ports cre­at­ing Short­cuts with the help of “Apple Intel­li­gence”. You only need to describe what the Short­cut should do. Apple Intel­li­gence does the rest.

The Code Generator in Crank

Crank takes a sim­i­lar approach with its built-in code gen­er­a­tor. In the set­tings under “Advanced”, you can enter a free API key from Google Gem­i­ni. You cre­ate the key with a free Google account at aistudio.google.com/api-keys. Alter­na­tive­ly, you can use Chat­G­PT through Apple Intel­li­gence. For this, Crank installs Apple Short­cuts that serve as the inter­face.

Image shows the Advamce setting screen. Here you can connect Crank script development  to Gemini

For a new rule, you now enter an instruc­tion instead of a script, here with the request to cre­ate a Swift script:

Create a Swift script that speaks the file name and the path when a new file is created in the folder, in German: Die Datei wurde im Pfad erstellt
Image shows the trigger screen with the script field containing the prompt for Gemini to create the script

After you click “Gen­er­ate code”, the script is cre­at­ed. In this exam­ple, I used my free Chat­G­PT account through the “Apple Intel­li­gence” inter­face, because calls to the Gem­i­ni API in my free account are inter­rupt­ed from time to time because of over­load.

After you approve the exe­cu­tion of the Short­cut, the fin­ished script is insert­ed in place of the prompt:

#!/usr/bin/swift
import Foundation

let env = ProcessInfo.processInfo.environment
guard let fileName = env["fileName"], let filePath = env["filePath"] else {
    exit(1)
}

let message = "Die Datei \(fileName) wurde im Pfad \(filePath) erstellt"

let task = Process()
task.launchPath = "/usr/bin/say"
task.arguments = [message]
task.launch()
task.waitUntilExit()

exit(0)

Controlling Crank with MCP

The sec­ond option is that an AI such as Claude, either in the desk­top app or with Claude Code in the ter­mi­nal, con­trols Crank direct­ly. For this, you first need to install the “crank com­mand line tool” in the set­tings under “Gen­er­al”.

Image shows the general setting screen. With the option to install the cli Crank tool

After that, you can start the Crank MCP serv­er under “AI agents” (“Enable MCP”) and con­nect it to an AI agent, here Claude Code and the Claude desk­top app. MCP (“Mod­el Con­text Pro­to­col”) is an inter­face through which AI appli­ca­tions can use exter­nal tools. Crank also sup­ports oth­er AI agents, such as Codex from Ope­nAI, GitHub’s Copi­lot CLI, Open­Code, and Google’s Gem­i­ni CLI.

Image shows the AI-agent settings screen fpr starting MCP Server and connecting AIs

With this, you can cre­ate rules by prompt direct­ly in the app or in the ter­mi­nal tool of the respec­tive AI provider. To do this, Claude con­nects to Crank, gets the infor­ma­tion it needs, cre­ates the code, and tests it.

Image shows the promt and the answer of an AI request

At the end, the fin­ished rule is cre­at­ed direct­ly in Crank, here with the name “Desk­top: neue Datei ansagen” (“Desk­top: announce new file”).

Image shows the the trigger screen with an AI generated rule

This way, even some­one who does not know the syn­tax of a script­ing lan­guage can have more com­plex scripts cre­at­ed. Still, you should have some pro­gram­ming expe­ri­ence, so that you can at least rough­ly under­stand what the script does.

Custom Triggers with Scripts

If the exist­ing trig­gers are not enough, Crank lets you write your own trig­ger. Instead of watch­ing for a sys­tem event, Crank runs a script at reg­u­lar inter­vals and uses the exit code to decide whether the rule fires. As an exam­ple, I had Claude, as an AI agent, build a rain warn­ing. The script checks the rain fore­cast for the next two hours for a defined loca­tion. If rain is expect­ed, a noti­fi­ca­tion shows when the rain starts and how much to expect. The script looks like this:

import json, sys, urllib.request
from datetime import datetime

# Coordinates for Heidelberg
LAT, LON = 49.40, 8.68
THRESHOLD_MM = 0.5   # Total for the next 2 hours

URL = (f"https://api.open-meteo.com/v1/forecast?latitude={LAT}&longitude={LON}"
       "&minutely_15=precipitation&forecast_minutely_15=8&timezone=Europe%2FBerlin")

# 1 Fetch data, abort silently on any error
try:
    with urllib.request.urlopen(URL, timeout=5) as r:
        data = json.load(r)
    times = data["minutely_15"]["time"]
    rain = data["minutely_15"]["precipitation"]
except Exception:
    sys.exit(1)

# 2 Decide, exit 1 means do nothing
total = sum(x or 0 for x in rain)
if total < THRESHOLD_MM:
    sys.exit(1)

# 3 Determine the start of the rain and the waiting time
first = next((t for t, x in zip(times, rain) if (x or 0) > 0), times[0])
minutes = max(0, int((datetime.fromisoformat(first) - datetime.now()).total_seconds() // 60))

# 4 Output data for the action
print(f"mm={total:.1f}")
print(f"start={first[11:16]}")
print(f"minutes={minutes}")

You enter the script in the “Script” trig­ger. Crank runs it every 600 sec­onds (“Poll every”). If it ends with exit code 0, the trig­ger fires. With any oth­er exit code, the rule is skipped. Lines in the for­mat key=value that the script prints are avail­able to the action as place­hold­ers {{key}}.

Custom Skript as Trigger in Trigger Screen

What Does the Script Do?

In the head­er, the required libraries are loaded and vari­ables are defined, name­ly the geo­graph­ic coor­di­nates (here Hei­del­berg) and the thresh­old from which rain is report­ed.

The vari­able URL con­tains the address of the weath­er ser­vice Open-Meteo, which is used to get the rain amounts for the next two hours. The para­me­ter minutely_15=precipitation defines that the amount of pre­cip­i­ta­tion should be request­ed, and forecast_minutely_15=8 asks for eight val­ues at 15-minute inter­vals, which is two hours.

import json, sys, urllib.request
from datetime import datetime

# Coordinates for Heidelberg
LAT, LON = 49.40, 8.68
THRESHOLD_MM = 0.5   # Total for the next 2 hours

URL = (f"https://api.open-meteo.com/v1/forecast?latitude={LAT}&longitude={LON}"
       "&minutely_15=precipitation&forecast_minutely_15=8&timezone=Europe%2FBerlin")

Next, the weath­er data is request­ed through the URL. The response from Open-Meteo is a JSON with the fore­cast data for the next two hours in 15-minute steps. From it, the times are stored in the list times and the amounts of pre­cip­i­ta­tion in the list rain. Entries at the same posi­tion belong togeth­er. If the request fails, for exam­ple because the ser­vice is not reach­able or does not answer with­in five sec­onds, the script ends with exit code 1.

# 1 Fetch data, abort silently on any error
try:
    with urllib.request.urlopen(URL, timeout=5) as r:
        data = json.load(r)
    times = data["minutely_15"]["time"]
    rain = data["minutely_15"]["precipitation"]
except Exception:
    sys.exit(1)

After that, the script cal­cu­lates whether at least 0.5 mm of rain falls in the next two hours. To do this, all val­ues of the list rain are added up and stored in the vari­able total. If total does not reach the thresh­old, the script again ends with exit code 1, and the rule does not fire.

# 2 Decide, exit 1 means do nothing
total = sum(x or 0 for x in rain)
if total < THRESHOLD_MM:
    sys.exit(1)

Next, the script finds the first point in time with­in the two hours at which, accord­ing to the fore­cast, rain starts. For this, the func­tion zip(times, rain) com­bines the val­ues from both lists “posi­tion by posi­tion” into pairs, each with one time and the match­ing pre­cip­i­ta­tion val­ue. next(...) takes the first point in time at which the pre­cip­i­ta­tion val­ue is greater than zero and stores it in first. Then the script cal­cu­lates how many min­utes remain until that time. If it is already in the past, the wait­ing time is set to zero.

# 3 Determine the start of the rain and the waiting time
first = next((t for t, x in zip(times, rain) if (x or 0) > 0), times[0])
minutes = max(0, int((datetime.fromisoformat(first) - datetime.now()).total_seconds() // 60))

In the last step, the script prints the val­ues for the noti­fi­ca­tion as key-val­ue pairs, so that the “Show Noti­fi­ca­tion” action can use them.

# 4 Output data for the action
print(f"mm={total:.1f}")
print(f"start={first[11:16]}")
print(f"minutes={minutes}")

You can use these val­ues as place­hold­ers in the “Title” and “Body” fields of the noti­fi­ca­tion, here {{minutes}}, {{mm}}, and {{start}}.

Image shows the notification settings in German laguage

As soon as rain is fore­cast, a noti­fi­ca­tion like this appears (here in ger­man).

Images shows a notification from the script

If the rain con­tin­ues, the “Trig­ger on” switch mat­ters.

Shows the trigger on alternatice "State Changes" and "Every Rub"

If the switch is set to “State Changes”, you only get a noti­fi­ca­tion when rain is fore­cast with­in the next two hours for the first time. Every fur­ther run still ends with exit code 0, but does not lead to a new noti­fi­ca­tion. Only when the fore­cast no longer con­tains any sig­nif­i­cant rain, or the ser­vice is not reach­able, does the script end with exit code 1 again. This resets an inter­nal flag, and at the next run with code 0, a noti­fi­ca­tion appears again.

If the switch is set to “Every Run”, a new noti­fi­ca­tion with updat­ed data appears at every run, which means every ten min­utes, as long as rain is fore­cast. Only when no more rain is expect­ed do the noti­fi­ca­tions stop. In both cas­es, this only applies if at least 0.5 mm of rain is fore­cast.

This is a sim­ple solu­tion that only warns you that it will rain at some point in the next two hours. It does not tell you when the rain stops again. Adding that would go beyond the scope of this arti­cle.

In sum­ma­ry, with a script trig­ger you can define your own events, for exam­ple to check sen­sors that the sys­tem’s built-in trig­gers do not cov­er, or to con­nect any exter­nal ser­vice.

Sharing Rules

You can share rules with oth­er Crank users. To do this, click the share icon, which is typ­i­cal for macOS, at the top right of the rule box. This copies a link to the clip­board that looks rough­ly like this (here the rain warn­ing as an exam­ple):

https://crank.lowtechguys.com/rule/YnZ4bvEEAACvAwAA4Ah7IjMiOiJub3RpZmljYXRpb24iLCIxMDQAFeADXC91c3JcL2JpblwvcHl0aG9uMwAcQBp2QAgxgAk0MeALe3ttbX19IG1tIGVyd2FydGV0LCBhYiB7e3N0AA4AGsAsVWhyQCsy73NjcmlwdFRyaWdnZXJlZAhCRjDoUmVnZW4gaW4ANOdtaW51dGVzADZQCk0Iikg7NuAZaW1wb3J0IGpzb24sIHN5cywgdXJsbGliLnJlcXVlc3RcbmZyb20gZGEAgORpbWUgIDAoEOAYXG5cbkxBVCwgTE9OID0gNDkuNDAsIDguNjhcblRIUkVTSE9MRF9NTQAc6zAuNSAgICMgU3VtAEjqZGVyIG7DpGNocwCN6iAyIFN0dW5kZW4IUMAvVVJM4CAoZlwiaHR0cHM6XC9cL2FwaS5vcGVuLW1ldGVvLmNvbVwvdjFcL2ZvcmVjYXN0P2wBYOZ0dWRlPXsAj-Z9JmxvbmcoEOhPTn1cIlxuIBgByQ1cIiby52x5XzE1PXAAQORpcGl0EZ9oTyZoI1_0iOo4Juh6b25lPUV1cgCG5yUyRkJlcmwBvIixIinmIyAxIERhCMjkaG9sZQFI7mJlaSBqZWRlbSBGZWhsAOrlc3RpbGwBvkBfYkjmaOR0cnk6GJPkd2l0aDl09UAPLgjtQQooiH0sIOxvdXQ9NSkgYXMgcjowygmFybxhID3x6C5sb2FkKHIpGB0IM8ghcyA98cjNW1wi98ARXCJdEbqYLSJd5HJhaW44LPABOSHzEDXoZXhjZXB0IEUQBwAVIJICPecuZXhpdCgxIRXmMiBFbnRzAPCJFWlkQBxFASlBGGIAYut0IG5pY2h0cyB0dQkP5G90YWwAhetzdW0oeCBvciAwIAGLir0geAigAFLIJmlmIPKaWTwg9jh9_ugzIEJlZ2lubgJpkwlzIIJicyCLSiBXgIt6ZUFqYsmOaW1t5WZpcnN0AH8A2-R0KCh0EHyYf3Qs5HppcCgRUFiKLECJICCkwAUpID4ZouRzWzBdAHsZPwl85G1heCgDC4BSaW4rLktMLsBgaXNv5G1hdCgQd8tOKSAt9egubm93KCkpLhDp619zZWNvbmRzKCkgCwLkIDYwKSDcYm4062bDvHIgZGllIEFrCYjnIGF1c2dlYgjRiHhwcgNC5G1tPXsQTuU6LjFmfRKwMBwUSJCGPXvnWzExOjE2XTgi9SDObD898QAfDDlGM-U2MDAuMAzQNIDiIn0GAAAAAAAAAGJ2eCQ

The rule is not stored on a serv­er. It is com­plete­ly con­tained in the link, com­pressed and Base64-encod­ed, but not encrypt­ed. Any­one who has the link can there­fore read its con­tent. The serv­er seems to act only as a bridge. It replaces the part https://crank.lowtechguys.com/ with crank://, so that when you open the link, the rule appears right away in an import win­dow in Crank.

Before you import a rule, you should always check what it does. A shared rule can run shell scripts on your com­put­er. Depend­ing on your secu­ri­ty set­tings, this may even hap­pen with­out a prompt. Every­thing that is in a rule is also in the link, such as paths, loca­tions, or cre­den­tials. You should keep this in mind before you share a rule.

If you want to bypass the serv­er, you can also edit the link your­self and replace https://crank.lowtechguys.com/ with crank://. If you enter this address in a brows­er, the rule is import­ed in the same way.

I do not know why the devel­op­ers chose this approach instead of sim­ply sav­ing the rule as a file that you could then share.

Conclusion

Crank joins a series of tools that help auto­mate cer­tain work­flows. Its strengths are the sim­ple imple­men­ta­tion of the trig­ger → con­di­tion → action approach, the large num­ber of trig­gers, and the sup­port­ed script­ing lan­guages. For sim­ple actions, you can use Apple Short­cuts. zsh is suit­ed for exist­ing com­mand-line tools, Python for web ser­vices and JSON pro­cess­ing, and a Swift script is a good choice for actions that need access to macOS frame­works. If you pre­fer anoth­er lan­guage, you can even add your own inter­preter.

There are also some points of crit­i­cism.

  • Switch­es are often far away from what they con­trol. The switch “Also run an action when the file is delet­ed” is at the bot­tom of the rule, but the relat­ed action appears in the upper part.
  • Con­di­tions are spread over sev­er­al places: the IF line, the “Watch Path”, and the “Con­di­tions” switch.
  • You can­not freely reorder rules in the list. Groups pro­vide some order, but more free­dom in sort­ing would be help­ful.

Pro­files are a prac­ti­cal way to put togeth­er rules for dif­fer­ent work con­texts. It is only a pity that you can move rules between pro­files with the con­text menu, but not copy them.

For sim­ple uses, the app is rea­son­ably intu­itive. But there are also more com­plex con­cepts that you can­not under­stand just by look­ing at them, such as “State Changes” ver­sus “Every Run” or “Throt­tle” ver­sus “Debounce”. More doc­u­men­ta­tion would help here, even though the slo­gan says “no man­u­al required”.

If you are look­ing for a sim­ple way to run scripts depend­ing on sys­tem events or on a sched­ule, you can get to your goal very quick­ly with Crank. How­ev­er, you need a min­i­mum of pro­gram­ming knowl­edge. Even if you only use ready-made rules from the inter­net or an AI to cre­ate them, you should have enough knowl­edge to at least rough­ly under­stand what the script does.

Fediverse Reactions

Leave a Reply

Your email address will not be published. Required fields are marked *