Omni Automation: Prerequisites & Task Dependencies

UPDATE 2021-02-14: Note that this plug-in has been updated substantially since this post was originally written. This post has now been updated to reflect those changes.

Context

Though OmniFocus has options for sequential and parallel action groups which provide some capacity for dealing with tasks which are dependant on each other, on occasion these are insufficient for my needs.

I generally run up against two scenarios where I find this set of automations useful:

  • Sometimes a task in one project can’t be started until a task in a second project has been completed. Despite this, they are still distinct projects. (An example of this: accounting work for two related (but distinct) parties.
  • Sometimes the “dependency” relationship could be reflected using the built-in sequential and parallel task action group structure, but the level of complexity is such that the nesting of tasks becomes difficult to manage or just unwieldy to look at. (As an example: university coursework, which is often broken down into weekly components that should be completed sequentially with assignments attached to this that shouldn’t block further coursework. Sometimes there are optional readings, or only part of the coursework needs to be done before you can complete a particular part of an assignment.)

In addition, there are some scenarios where the way I am thinking about a task is in terms of “sequential projects”. Again, university coursework is a good example here: in my mind, each week’s content is its own project. But they still need to be done in order i.e. each week is dependant on the previous week.

Solution

I have written a plugin that contains a series of Omni Automation Scripts that use tags (🔑 and 🔒) to designate one task as being dependant on another.

In addition, the ‘notes’ field is used to track more specific details of the prerequisite/dependant tasks:

  • A prerequisite task will have a note similar to [ DEPENDANT: omnifocus:///task/elnhPEQEJzq ] Task 2
  • A dependant task will have a note similar to [ PREREQUISITE: omnifocus:///task/mEur73AEC07 ] Task 1

This means that a task can have more than one dependant or prerequisite task, which allows for greater complexity.

Here is a quick video of the plug-in in action:

Usage Details

To make one or more tasks a prerequisite of one or more other tasks:

  1. Tag the prerequisite task(s) with Make Prerequisite (or run the Make Prerequisite action which does this for you). 
  2. Select the dependant task(s).
  3. Run the ‘Add Prerequisite’ Omni Automation Script.

Instead of marking a task complete, you can run the Complete For Prerequisite action; note that this will also work just fine on tasks that are not prerequisites. 

You might wish to assign keyboard shortcuts to each of the above actions to make this easier.

Optionally:

  • You can run the Check Prerequisites action as a backup, perhaps as part of a daily or weekly review or automatically using a tool like Keyboard Maestro (a downloadable macro is now included below as of 2021-02-20). This checks all the tasks that are waiting and, if all their dependent tasks have been completed, makes them available.
  • You can run the Update Due Dates action, which updates the due dates on the prerequisite task, and any sequential actions that precede it, to match the earliest due date of its dependent tasks.
  • You can also use functions available in the dependencyLibrary in your own scripts:
    • getDependants: get a list of a specific task’s dependent tasks
    • getPrereqs: get a list of a specific task’s prerequisite tasks
    • checkDependants and checkDependantsForTaskAndAncestors to check a prerequisite task for input and, if any of its dependent tasks have been completed, updates the tasks as needed.

OmniFocus Set-Up

  1. Create the following three tags. (In my database, I have these set up as subtags under a parent ‘Dependency’ tag.)
    • Make Prerequisite: This is a temporary tag. Refer to the ‘Usage Notes’ below for details of how this is used.
    • 🔑: This tag denotes a task that is required to be completed before another (dependant) task becomes available.
    • 🔒: This tag denotes a task that is currently unavailable because it is waiting for another task to be completed.
  2. Set the status of the 🔒 tag to ‘on hold’ (to reflect the fact that you can’t make any progress on these items until the prerequisite task has been completed).

OmniFocus Plug-In

The plugin can be downloaded from GitHub here. At that link you will find instructions for installing the plug-in and further details about all of the available actions and functions it contains.

Keyboard Maestro Macro (optional) [added 2020-02-20]

This Keyboard Maestro runs the Check Prerequisites action and so can be set up to run regularly: Run OF Plugin: Check Prerequisites

28 thoughts on “Omni Automation: Prerequisites & Task Dependencies”

  1. Great script ideas! I look forward to using such approaches to run automation on macOS and iOS.

    I have two thoughts, with a pardon up front because I am not conversant in the syntax or best practices of the scripting language. First, I see that the tags that are used are exposed at the start of the function calls. Would they be better placed as globals external to the function call? I am used to seeing such globals in pubic-distributions of the AppleScripts for OmniFocus. Secondly, how do the scripts handle cases where the note field already has content? For example, I have an AppleScript that populates the note field with a URL callback. This allows me to link projects or tasks to external content (in the case, figures associated with the project that are located on Kanban boards in Curio). Will your script respect the pre-existing note field content?

    My second question prompts me to think over my own approach in using the note field to hold URL callbacks. I have to say that at some point, I must wonder whether we will have to request that OmniGroup include user-defined meta fields for projects or tags. That way, we can avoid programming to handle cases where different scripts set/reset/delete the entire note field because they think it is entirely their own private meta-container. Alternatively, this question may give pause to think about the utility and eventual need for <meta=taskdependencies> container designations to surround the script content within the note field itself so as to restrict the potential destructive actions of scripts to their own boxes.

    1. Thanks Jeffrey! I am very excited by the possibilities that Omni Automation affords. It’s already very powerful and I suspect the Omni team still have a lot they would like to add. (I hope so!)

      In response to your first question: you are possibly right. I am a Javascript amateur myself (accountant by day; wannabe coder by night), so it’s more than likely that the code is imperfect. It may be the case that it would be best practice to place them outside the function call. I should do some experimentation and research on this and adjust if needed. (I actually would ideally put these in a config file separately too but I’m experiencing some inconsistency with getting that to work, so I need to play around with that a bit more.)

      Re the second question: I also like to use URLs (and occasionally actual notes) in the notes field, so the scripts add the [DEPENDANT:] or [PREREQUISITE:] tags to the beginning of the note and should leave everything else in tact. (You might, if anything, end up with some extra white space when a prerequisite task is marked as completed and the tag deleted from the dependent task—-the regular expressions might need a little tweaking in this regard.)

      I think that would be an interesting addition to OmniFocus and I think you make a valid point regarding the potentially destructive nature of using the notes field in this way and the possible options. For me I have chosen this format and will probably stick with it—-because at this stage I think it is unlikely to conflict with other scripts. [PREREQUISITE: omnifocus:///task/taskID] (or similar) is not something I expect to come up naturally in any of my notes in the near future!

      1. I find that using a header-type configuration is generally the easiest approach to maintain in scripts that I know may end up mostly in the hands of technically-knowledgeable users. It does however open the door to the potential for non-tech-inclined users to munge the code when all they wanted was to change a preference. The balance is that it avoids having to manage yet another file in addition to the files that are purely the code base.

        I like your approach to use [META-NAME: …] as a container for script variables in the notes field in OmniFocus. I will have to “borrow” it. I see an immediate benefit in my AppleScript that links Curio OmniFocus with URLs in the OF note field. It will allow me to avoid having to wipe the note field clean each time I make a link.

        As a colleague in another forum said, you have a text-parsing problem and decide to use REGEX to solve it. Congratulations, now you have two problems.

        1. I think I will still need to have configuration in the header that links to the config file, so I think as a compromise I will likely end up using this but with some configuration information/example settings commented out. I’m starting to use the same tags between scripts and I’d like to minimise fiddling if I decide to change the nesting or the name or something in my OF database.

          Borrow away!

    2. Incidentally, I’ve just done some quick testing and moving the tags used outside of the function calls throws an error and breaks the script. So, I think I’ll stick with leaving them where they are for now!

  2. Hi Kaitlin,

    This is great. I am a complete rookie when it comes to OF Automation but this has been a very helpful introduction. I would love to take this one step further and have the dependent task become DUE when the prerequisite action is completed as opposed to just available. Any help you can provide on how that might work would be much appreciated.

    1. Hi David!

      I believe if you add a line inside dependencyLibrary.js before dependantTask.removeTag(dependantTag); (i.e. line 46 on Github) that says:

      dependantTask.dueDate = new Date();

      That should achieve what you are aiming for!

      1. Awesome, thanks so much! Is there a way for me to access the code within depedencyLibrary.js to add that line?

        1. Hi David! Sorry for leaving you hanging! The post above links to an old version of the plugin (I need to update it and also write a proper README file), so I would recommend heading to the repository on Github (here: https://github.com/ksalzke/dependency-omnifocus-plugin), downloading all the files – once unzipped you’ll be able to make the change in that file and then you will just need to make sure all the files are in a folder and rename that folder with the extension ‘.omnifocusjs’. Let me know if that explanation is unclear though!

          1. Hi Kaitlin, I have so been loving your dependency shortcut – life changing!! Unfortunately, for some reason it just stopped working for me all of a sudden. When I add the ‘make prerequisite’ tag to something and then go to another task to ‘add prerequisite’ via the plugin ‘add prerequisite’ is grayed out and not available to choose – any idea what could have caused this problem?

          2. Hi David! So glad you’re finding it useful! Not very helpful, I know, but this is still working for me, at least on OmniFocus 3.9.2 on macOS. If the menu item is greyed out it sounds like it is failing validation, which is unusual because the only conditions should be a) one project or task is selected and b) there is more than one task tagged with the ‘make prerequisite’ tag. It sounds like that should be the case! The only thing I might suggest is re-downloading from Github (and following the same steps in my last comment) to see if that fixes the issue for you? Sorry that answer is not more useful!

  3. Thanks for the response – yes, ultimately I ended up reinstalling it and got it to work again! Thanks again – it really is life changing!!

  4. Hi Kaitlin, I had this issue happen again, so I redownloaded and reinstalled…it looks like you recently changed it a little bit…now I am seeing four options 1) Add Prerequisite 2) Check Prerequisites 3) Complete for Prerequisite and Make Prerequisite…unfortunately ‘add prerequisite’ is still greyed out…any ideas what could be causing that?

    1. Oops, sorry David! I think I accidentally committed a change to the config file which might have broken this for you. I’ve updated slightly now; could you try re-downloading the most recent version and see if that gets it working again for you?

  5. Hey Kaitlin, jus want to start off by saying thanks for building this. I’ve been able to get everything to work but the “complete for prerequisite” script. I keep getting the error below and wanted to see if you might know how to fix it.

    TypeError: null is not an object (evaluating ‘PlugIn.find(“com.KaitlinSalzke.functionLibrary”).library’) /Users/Angel/Library/Mobile Documents/iCloud~com~omnigroup~OmniFocus/Documents/Plug-Ins/dependency-omnifocus-plugin-master.omnifocusjs/Resources/dependencyLibrary.js:73:67

    I went to line 73 in the dependencyLibrary file and the only thing I saw was that it was trying to do something with the functionLibrary but I didn’t see that file in the resources folder so I copied the code above and added it. That was my best guess on how to fix it but I’m pretty much stumped at this point.

    1. Hi Angel! This post is a little out of date (I need to update it). I would recommend heading to https://github.com/ksalzke/dependency-omnifocus-plugin to get the latest version–there are instructions there which should be more up-to-date.

      That said, the function library is a separate plugin, which you can get from https://github.com/ksalzke/function-library-for-omnifocus. I had neglected to mention that it was required in my set-up instructions at all (even in the most recent version) so thank you for bringing that to my attention! Let me know if you need any more help getting started.

  6. Kaitlin, it looks like you’re solving a major problem for my workflow, so I’m looking forward to getting this working. But I’m getting an error when I try to run the Add Prerequisite automation:

    Error: Function Task.addTag argument “tag” at index 0 requires a non-null value /Users/[username]/Library/Containers/com.omnigroup.OmniFocus3/Data/Library/Application Support/Plug-Ins/Dependency.omnifocusjs/Resources/addPrerequisite.js:14:18

    Any ideas?

    1. Hi Ivey – thanks for your patience – I have a newborn so it’s taken me a few days to get back to you! That suggests that you don’t have the tags set up in your OmniFocus database yet. I think you will need to either: (1) create tags named “Make Prerequisite”, “🔑”, and “🔒” in your OmniFocus database (these match the default configuration) or (2) create a different set of tags and edit the dependencyConfig.js file to reflect the tags you want to use to denote these tasks, if the defaults don’t work for you.

      Let me know how you get on. 🙂

      1. Yep, that was what I was missing. I had “Make Prerequisite” (actually just PreReq for me, I’d already adjusted the config file), but hadn’t added the 🔑 or 🔒 yet.

        Many thanks!! And congrats!

    2. Hello Ivey,
      I encountered the same issue and was able to solve it by adding a blank after the “lock” emoticon in the Dependant tag. Hope this helps.
      Best, Adrian

  7. Hi Kaitlin,

    I just wanted to thank you for this great plugin. It’s an incredibly creative solution to a very common and practical use case in my Omnifocus workflow!

    One thing I noticed: When adding the suggested tags to OmniFocus, it’s necessary to add a blank after the lock icon for the Dependant tag. Without, there’s an error message.

    Took me a while to figure out why it wasn’t working at first – perhaps you can add a comment in the instructions.

    Best,
    Adrian

    1. Hi Adrian,

      So glad you’ve found it useful!

      That is certainly odd – it shouldn’t be necessary, I’ve just double checked (and in fact, I don’t have a space in my database). My only thought is that as the plugin uses OmniFocus’s built-in “fuzzy matching” to find the first tag matching 🔒, perhaps it is matching with something else? In any case, I’m glad you’ve got it working and I’ll keep that in mind in case anyone else has any problems – thank you!

  8. You’re wonderful! My entire life is based on prerequisites and everything’s connected to each other. Without this function all the program would be useless. I’ve tried it on the latest 3.11.2 and it works.

    You can just write setup instructions a bit more clearly, even trying to find the tag names took me a while since it was in other section of paragraph, also adding emojis took me a while, also you’ve written ‘dependent’ differently, had to look at the script to find the correct version. Other than that, you’re an angel!

    For the clarified version:

    Download and double click the script file while omnifocus is open
    Make a tag named ‘Dependency’
    Make tags named ‘Make Prerequisite’ ‘🔑’ and ‘🔒 Dependant’ (for emojis, in the top toolbar click edit-emoji&symbols
    Drag those three tags into ‘Dependency’ tag
    Select the task you want to be prerequisite and enter the ‘make prerequisite’ tag manually
    Select the task you want to be dependent to that prerequisite and click automation – dependency – add prerequisite from the top toolbar (if you’ve missed the previous step, it will be grayed out!)
    To complete the prerequisite select the task and click automation – dependency – complete for prerequisite in the toolbar

    1. Thanks Yigit! So glad you’ve found it useful.

      Thank you for the feedback – I actually need to update this post, so I’ll bear that in mind when I do so. 🙂

  9. Hi Kaitlin,

    first of all I want to thank you for this amazing plug-in, it’s exactly what I was missing in OmniFocus.

    I noticed just a thing that could be improved: the “Make prerequisite” action doesn’t work on projects. The workaround is very easy though, since I can add the tag manually to the project, then run “Add prerequisite” to the tasks or projects I want to be dependent on it and it all works as it should.

    Best,

    Marco

  10. Hi Kaitlin,

    after using the dependency script bundle for a while already, I just discovered the “update due dates” script – sounds so useful!

    Everything else is working flawlessly. But for some reason this script doesn’t have the intended effect when I run it.

    This is what I did:
    1) Create a dependent task that requires a prerequisite to be completed before it’s available.
    2) Set the due date for this dependent task to tomorrow
    3) Run the “update due dates” script (I did ensure no task was selected and that the icon was not greyed out. To be sure, I also called it through the Automation menu)

    Result: Nothing happens. If I’m not mistaken then the expected behavior would be that the prerequisite task receives the same due date as the dependent task, correct?

    Do you have any troubleshooting advice?

    Best, Adrian

    1. Hi Adrian,

      It’s not you, it’s me! I’m pretty confident I broke this somewhere along the way. What you have describe is indeed how it should work, but right now it doesn’t.

      This too is on my list to investigate and fix (probably not in the very near future, sadly!) but I will be sure to pop a comment back here when I do so you can test it out for me.

Leave a Reply