AppleScript for Pulling Today’s Completed Tasks From Things
Balancing life’s necessary chores with meaningful progress toward our goals can be challenging, especially when greeted by an overflowing task list each morning.
To tackle this, I’ve been exploring ways to not just manage my tasks in Things but also to ensure I’m making real headway on projects that matter. In this post, I’ll show you how an AppleScript is helping me do just that.
Chores vs. Progress
As I explained in a YouTube video, all my tasks (even chores/habits) are in Things. I am just more successful when all of my tasks are in one place.
The downside is that I often wake up with 50 or so tasks in my Today view, and it can be easy to complete a bunch of tasks that are important life maintenance things but make little to no real progress on new projects/work.
So, I have been experimenting with various ideas to reflect on my efforts each day and make sure I am making progress instead of just doing chores.
Clear to Neutral
Since changing careers, this subject is due for a new post, but I have written before about my Clear to Neutral process. This end-of-the-work-day routine helps me create a clean break between the work day and my personal time. It’s also a great opportunity to reflect on the day and plan for the future.
One of the things I do in my current version of clearing to neutral is journaling in Day One. Inspired by the book Triggers by Marshall Goldsmith, I have three prompts that force me to evaluate my accomplishments for the day. My prompts are:
- What did I achieve today?
- Were these the most important things I could have done today?
- How do these completed tasks contribute to my short-term or long-term goals?
I have tried several different prompts over the past six or so months, and these three are my favorite yet, but we will see.
AppleScript vs Shortcut
It turns out that I find it easy to lie to myself, especially if there is an impending deadline for a project I am procrastinating on. I can easily clean the microwave and do a bunch of other chores, so I can tell myself I got a bunch of stuff done today while those deadlines inch closer.
I needed an objective account of the work I do on a day so I can make sure I don’t try to convince myself that a day of checking boxes is the same as doing work.
While I could use the Logbook feature of Things to manually review my day, I found it difficult to look at the logbook and have a clear understanding of what tasks I did that made forward progress on my goals.
So, of course, I looked to an automation.
Chore Tag
To help me differentiate chore-type tasks from tasks that move me toward a goal, I use a “chore” tag to separate out these important but not progress-making tasks. The rest of this post depends on having this chore tag.
Shortcuts
As I have shared in the past, I am pretty mac-centric these days, and Shortcuts is not the first tool I reach for. However, Things has been working hard on its Shortcuts integration, so I started with Shortcuts.
You can see my Shortcut here, but it is incomplete. Or at least I abandoned it before I achieved the result I wanted.
As I said before, I want a list of all the actions I completed today that are not tagged with “chore.” But I would also love to have them grouped by the Area they are in, in Things.
This Shortcut allowed me to break out completed (not canceled) tasks from Things by Area, but if a task was part of a project in an Area, it would not appear in the list.
I am sure someone better with Shortcuts than me could make this work as intended, but I have been having a lot of success with ChatGPT and AppleScript, so I moved on.
AppleScript
After a bunch of trial and error, ChatGPT and I came up with this script, which pulls all of the completed (not canceled) tasks from today, whether or not they are part of a project. Then, it groups the tasks by Area, makes them into a bulleted list, and creates a new “After Work” journal entry in Day One with my prompts and the completed tasks inserted appropriately.
I’m very happy with the result, and I’m excited to share it with you! But first, I want to point out that this requires the Day One Command Line Interface tool to be installed. It was very easy to do, but you will need to complete that process before this script will work.
(*
Things3 to Day One Work Journal Integration
Version: 2.0
Created by: Mike Burke (https://www.themikeburke.com) and Claude (Anthropic)
Last Updated: 2025-02-02
License: MIT
Copyright (c) 2025 Mike Burke
Permission is hereby granted to use, copy, modify, and share this script freely,
provided the above copyright and attribution notices are preserved.
Full license text: https://opensource.org/licenses/MIT
Description:
This AppleScript automates the creation of daily work journal entries by pulling completed tasks from Things3 and creating a structured entry in Day One. It filters out specified routine tasks and organizes the remaining tasks by their respective areas, providing a clean daily work log with customizable prompts for reflection on achievements and energy management.
Functionality:
1. Retrieves and processes completed tasks from Things3
2. For each task completed today, it:
a. Extracts the task name and organizational context (area/project)
b. Groups tasks by their associated area
c. Preserves and transfers:
- Task names
- Area/Project hierarchies
- Completion status
d. Filters out tasks with specified tags (default: "chore")
e. Handles multiple scenarios:
- Tasks within projects: Uses the project's area
- Standalone tasks with areas: Uses the task's direct area
- Tasks without areas: Groups under "No Area"
f. Generates a formatted Markdown entry with:
- Task listings grouped by area
- Customizable reflection prompts
- Consistent Markdown formatting for Day One
Usage:
1. Install and configure the Day One CLI:
- Default installation path is /usr/local/bin/dayone2
- Verify your installation path and update the script if needed
2. Customize the script (optional):
- Modify the filter tag ("chore") to match your Things3 organization
- Adjust the entry title ("After Work Entry")
- Customize reflection questions to match your journaling practice
3. Ensure Things3 is running and contains completed tasks
4. Run the script after your workday to generate a structured journal entry
Note:
- Requires Things3, Day One (with CLI installed), and macOS
- Tasks must be completed on the current day to be included
- The script assumes a "Work Journal" exists in Day One
- Customization points are clearly marked in the script with comments
- Default filtering uses a "chore" tag, but this can be modified to match your workflow
*)
tell application "Things3"
-- Get today's date and set the time to the beginning of the day
set today to current date
set time of today to 0
-- Format the date in ISO 8601 (YYYY-MM-DD) format
set isoDate to (year of today as string) & "-" & text -2 thru -1 of ("0" & (month of today as integer)) & "-" & text -2 thru -1 of ("0" & (day of today as string))
-- Initialize a list to store completed tasks
set completedTasks to {}
-- Fetch all completed to-dos from the Logbook list that were completed today
set todaysToDos to to dos of list "Logbook" whose completion date ≥ today and status is completed
-- Process each of today's completed to-dos
repeat with toDo in todaysToDos
-- Get the tags associated with the to-do
set toDoTags to tag names of toDo
-- CUSTOMIZATION POINT: Task Filtering
-- Modify the tag name "chore" below to match your Things3 tag for tasks you want to exclude
-- Remove this condition entirely if you want to include all tasks
if toDoTags does not contain "chore" then
-- Get the name of the to-do
set toDoName to name of toDo
-- CUSTOMIZATION POINT: Default Area Name
-- Change "No Area" below if you prefer a different label for unorganized tasks
set toDoArea to "No Area"
-- Check if the to-do has a project, and if so, check the project's area
if project of toDo is not missing value then
set toDoProject to project of toDo
if area of toDoProject is not missing value then
set toDoArea to name of area of toDoProject
end if
else if area of toDo is not missing value then
-- If there's no project, but the to-do has an area, use that area
set toDoArea to name of area of toDo
end if
-- Check if this area already exists in the completedTasks list
set areaExists to false
repeat with areaTask in completedTasks
if item 1 of areaTask is equal to toDoArea then
-- If the area exists, add the to-do to this area
set areaExists to true
set end of (item 2 of areaTask) to toDoName
end if
end repeat
-- If the area does not exist, create a new area entry and add the to-do
if areaExists is false then
set end of completedTasks to {toDoArea, {toDoName}}
end if
end if
end repeat
-- CUSTOMIZATION POINT: Entry Introduction
-- Modify the introduction text below to match your preferred entry style
set markdown to "Here are the non-chore tasks that I completed today:" & return & return
-- Add the tasks grouped by area to the markdown content
if (count of completedTasks) > 0 then
repeat with areaTask in completedTasks
set areaName to item 1 of areaTask
-- CUSTOMIZATION POINT: Header Level
-- Modify the "##" below if you prefer a different header level for areas
set markdown to markdown & "## " & areaName & return & return
repeat with task in item 2 of areaTask
set markdown to markdown & "- " & task & " " & return & return
end repeat
set markdown to markdown & return
end repeat
else
-- CUSTOMIZATION POINT: Empty Day Message
-- Modify this message for days with no completed tasks
set markdown to markdown & "No non-chore tasks completed today." & return
end if
end tell
-- CUSTOMIZATION POINT: Entry Structure
-- Modify the entry title and reflection questions below to match your journaling practice
set fullEntry to "# After Work Entry" & return & "###### What did I achieve today?" & return & markdown & return & return & "###### What energized or depleted me today?" & return & return & "###### How can I best use my remaining energy today?"
-- CUSTOMIZATION POINT: Day One Configuration
-- Verify that the Day One CLI path matches your installation
-- Update the journal name if you use a different journal for work entries
do shell script "/usr/local/bin/dayone2 new " & quoted form of fullEntry & " --journal='Work Journal'"
AppleScript for a Markdown File
I was having some issues with Day One not properly formatting the markdown text when I copied and pasted it into my After Work entry. After several rounds with the Day One support team, we could not figure out why, which is where the Day One CLI tool came into the picture.
While the Day One CLI ends up working better for me, I wanted to share the version of the script that produces a markdown file on the desktop, too, in case that works better for your workflow.
(*
Things3 to Desktop Markdown Export
Version: 2.0
Created by: Mike Burke (https://www.themikeburke.com) and Claude (Anthropic)
Last Updated: 2025-02-02
License: MIT
Copyright (c) 2025 Mike Burke
Permission is hereby granted to use, copy, modify, and share this script freely,
provided the above copyright and attribution notices are preserved.
Full license text: https://opensource.org/licenses/MIT
Description:
This AppleScript exports completed tasks from Things3 to a dated Markdown file on your desktop. It filters out routine chores and organizes tasks by their respective areas, creating a clean daily log that can be used with any Markdown-compatible system or note-taking application.
Functionality:
1. Retrieves and processes completed tasks from Things3
2. For each non-chore task completed today, it:
a. Extracts the task name and organizational context (area/project)
b. Groups tasks by their associated area
c. Preserves and transfers:
- Task names
- Area/Project hierarchies
- Completion status
d. Filters out tasks with the "chore" tag
e. Handles multiple scenarios:
- Tasks within projects: Uses the project's area
- Standalone tasks with areas: Uses the task's direct area
- Tasks without areas: Groups under "No Area"
f. Creates a formatted Markdown file with:
- ISO 8601 dated filename (YYYY-MM-DD - Today's Completed Tasks.md)
- Tasks grouped by area with consistent header hierarchy
- UTF-8 encoding for universal compatibility
Usage:
1. Ensure Things3 is running and contains completed tasks
2. Run the script after your workday
3. Find the generated Markdown file on your desktop:
- Filename format: "YYYY-MM-DD - Today's Completed Tasks.md"
- Contains a hierarchical list of completed non-chore tasks
- Organized by area with Markdown formatting
Note:
- Requires Things3 and macOS
- Tasks must be completed on the current day to be included
- Writes to desktop with UTF-8 encoding for maximum compatibility
- Will overwrite existing file with same name if present
- Default filtering uses a "chore" tag, but this can be modified to match your workflow
*)
(*
[Previous documentation header would go here]
*)
tell application "Things3"
-- Get today's date and set the time to the beginning of the day
set today to current date
set time of today to 0
-- Format the date in ISO 8601 (YYYY-MM-DD) format for filename
set isoDate to (year of today as string) & "-" & text -2 thru -1 of ("0" & (month of today as integer)) & "-" & text -2 thru -1 of ("0" & (day of today as string))
-- Initialize a list to store completed tasks
set completedTasks to {}
-- Fetch all completed to-dos from the Logbook list that were completed today
set todaysToDos to to dos of list "Logbook" whose completion date ≥ today and status is completed
-- Process each of today's completed to-dos
repeat with toDo in todaysToDos
-- Get the tags associated with the to-do
set toDoTags to tag names of toDo
-- CUSTOMIZATION POINT: Task Filtering
-- Modify the tag name "chore" below to match your Things3 tag for tasks you want to exclude
-- Remove this condition entirely if you want to include all tasks
if toDoTags does not contain "chore" then
-- Get the name of the to-do
set toDoName to name of toDo
-- CUSTOMIZATION POINT: Default Area Name
-- Change "No Area" below if you prefer a different label for unorganized tasks
set toDoArea to "No Area"
-- Check if the to-do has a project, and if so, check the project's area
if project of toDo is not missing value then
set toDoProject to project of toDo
if area of toDoProject is not missing value then
set toDoArea to name of area of toDoProject
end if
else if area of toDo is not missing value then
-- If there's no project, but the to-do has an area, use that area
set toDoArea to name of area of toDo
end if
-- Check if this area already exists in the completedTasks list
set areaExists to false
repeat with areaTask in completedTasks
if item 1 of areaTask is equal to toDoArea then
-- If the area exists, add the to-do to this area
set areaExists to true
set end of (item 2 of areaTask) to toDoName
end if
end repeat
-- If the area does not exist, create a new area entry and add the to-do
if areaExists is false then
set end of completedTasks to {toDoArea, {toDoName}}
end if
end if
end repeat
-- CUSTOMIZATION POINT: File Header
-- Modify the title format below to match your preferred document style
set markdown to "# Today's Completed Non-Chore Tasks (" & isoDate & ")" & return & return
-- Add the tasks grouped by area to the markdown content
if (count of completedTasks) > 0 then
repeat with areaTask in completedTasks
set areaName to item 1 of areaTask
-- CUSTOMIZATION POINT: Header Level
-- Modify the "##" below if you prefer a different header level for areas
set markdown to markdown & "## " & areaName & return
repeat with task in item 2 of areaTask
set markdown to markdown & "- " & task & return
end repeat
set markdown to markdown & return
end repeat
else
-- CUSTOMIZATION POINT: Empty Day Message
-- Modify this message for days with no completed tasks
set markdown to markdown & "No non-chore tasks completed today." & return
end if
end tell
-- CUSTOMIZATION POINT: File Naming
-- Modify the file name format below to match your preferred naming convention
set filePath to (path to desktop as text) & isoDate & " - Today's Completed Tasks.md"
-- Error handling for file operations
try
-- Open the file for writing; overwrite if it exists
set fileReference to open for access file filePath with write permission
-- Clear the file content
set eof fileReference to 0
-- Write the markdown data to the file with UTF-8 encoding
write markdown to fileReference as «class utf8»
-- Close the file
close access fileReference
on error errMsg number errNum
-- If there's an error, try to close the file and print an error message
try
close access file filePath
end try
display dialog "Failed to create markdown file: " & errMsg buttons {"OK"} default button "OK"
end try
Iterative Improvement of Automations
I am really excited/proud of this result (which is why I am writing this post), but I want everyone who reads this far to know that these huge, complicated scripts always start with a tiny seed of an idea and often expand over time to be what you see in a blog post.
I recently found an amazing new script for working with Things to create a Weekly Review project. My first thought was, “How does someone know how to do this, I could never make something so cool!” While Evan is undoubtedly skilled and intelligent, I wanted to take a second to let you, the reader, know that you should start pulling on the digital threads in your life that seem interesting, you never know what you will create in the end. Also, ChatGPT is awesome for helping with these types of projects!
Closure
I think this process of reflecting on my day and purposefully thinking about how I am spending my time has been beneficial. Sometimes, I notice that the day was full of deceptive productivity, and I spent most of my time in maintenance mode. Other days, this practice has highlighted achievements that slipped by because I was on a roll, and things felt effortless.
Both forms of reminder are helpful for learning more about my brain and getting better at managing it.
Leave a Reply
Want to join the discussion?Feel free to contribute!