Skip to content

Instantly share code, notes, and snippets.

@koke
Created February 5, 2026 12:32
Show Gist options
  • Select an option

  • Save koke/c581a324a3d9d098f537927e17fab3e3 to your computer and use it in GitHub Desktop.

Select an option

Save koke/c581a324a3d9d098f537927e17fab3e3 to your computer and use it in GitHub Desktop.
Things3 skill for Claude Code - manage your to-do list from Claude Code
name description allowed-tools
things
Manage Things3 to-dos from the command line. Use when the user wants to see their tasks, add new tasks, or manage existing tasks. Triggers on mentions of "things", "tasks", "to-do", "today's tasks", etc.
Bash

Things3 Task Management

Use the things command to interact with the user's Things3 to-do list.

Usage Context

Things3 is used for day-to-day task management:

  • Tasks planned for TODAY
  • Tasks scheduled for specific future dates
  • Reminders to revisit something later (e.g., "next week")

Tasks are action-oriented items for specific days, not a general project management system.

Available Commands

things today                      # List today's tasks
things add <task> [tags] [notes]  # Add task to today
things complete <task>            # Mark task as complete
things cancel <task>              # Mark task as cancelled
things delete <task>              # Delete task
things reschedule <task> <date>   # Move task (today|tomorrow|someday|+N)

When to List Tasks

IMPORTANT: Only list tasks when explicitly requested. Do not proactively list tasks at the beginning of every session.

Run things today when:

  • User explicitly asks to see their tasks or what's on their plate
  • User mentions "tasks", "to-do", or "things" in a way that suggests they want to see the list

When to Add Tasks

Add tasks when the user:

  • Explicitly asks to add something to their to-do list
  • Mentions they need to remember to do something later
  • Identifies a follow-up task during conversation

Do NOT add tasks for:

  • Things the user is doing right now in the current conversation
  • Every minor step in a larger task
  • Tasks that are part of the current work session

Tag System

The user uses tags to categorize action types. Common tags:

  • Testing - Something that needs to be tested
  • Deploy - Something that needs to be deployed
  • Video - Video to watch
  • Review - Code or content to review

When adding tasks, infer the appropriate tag based on the task description.

Task Matching

For commands that operate on existing tasks (complete, cancel, delete, reschedule), the task name is matched with contains, so you can use a unique substring of the task name rather than the full name.

Examples

# List today's tasks
things today

# Add a task with tag and notes
things add "Review PR #123" "Review" "https://github.com/org/repo/pull/123"

# Complete a task
things complete "Review PR"

# Reschedule to tomorrow
things reschedule "Video" "tomorrow"

# Move to someday
things reschedule "Deploy feature" "someday"

Output Format

Tasks are displayed as:

[Tag] Task name - notes/URL

Example:

[Testing] Fix date picker validation - https://example.com/issue/123
#!/bin/bash
# Things3 CLI wrapper
# Usage:
# things today - List today's tasks
# things add <task> [tags] [notes] - Add task to today
# things complete <task> - Mark task as complete
# things cancel <task> - Mark task as cancelled
# things delete <task> - Delete task
# things reschedule <task> <date> - Move task to different date (today|tomorrow|someday|+N)
cmd="${1:-today}"
shift
case "$cmd" in
today|list)
osascript <<'EOF'
tell application "Things3"
set todoList to to dos of list "Today"
repeat with todo in todoList
set output to ""
-- Add tags as prefix if exist
try
set tagStr to tag names of todo
if tagStr is not "" then
set output to "[" & tagStr & "] "
end if
end try
-- Add task name
set output to output & name of todo
-- Add notes if exist
try
set noteText to notes of todo
if noteText is not "" then
set output to output & " - " & noteText
end if
end try
log output
end repeat
end tell
EOF
;;
add)
task_name="$1"
task_tags="${2:-}"
task_notes="${3:-}"
if [[ -z "$task_name" ]]; then
echo "Usage: things add <task> [tags] [notes]" >&2
exit 1
fi
osascript - "$task_name" "$task_tags" "$task_notes" <<'EOF'
on run argv
set taskName to item 1 of argv
set taskTags to item 2 of argv
set taskNotes to item 3 of argv
tell application "Things3"
set newTodo to parse quicksilver input taskName
-- Add tags if provided
if taskTags is not "" then
set tag names of newTodo to taskTags
end if
-- Add notes if provided
if taskNotes is not "" then
set notes of newTodo to taskNotes
end if
-- Schedule for today
schedule newTodo for (current date)
return "Added: " & name of newTodo
end tell
end run
EOF
;;
complete|done)
task_name="$1"
if [[ -z "$task_name" ]]; then
echo "Usage: things complete <task>" >&2
exit 1
fi
osascript - "$task_name" <<'EOF'
on run argv
set taskName to item 1 of argv
tell application "Things3"
set matchingTodos to to dos of list "Today" whose name contains taskName
if (count of matchingTodos) = 0 then
error "No task found matching: " & taskName
end if
set targetTodo to first item of matchingTodos
set completion date of targetTodo to (current date)
return "Completed: " & name of targetTodo
end tell
end run
EOF
;;
cancel)
task_name="$1"
if [[ -z "$task_name" ]]; then
echo "Usage: things cancel <task>" >&2
exit 1
fi
osascript - "$task_name" <<'EOF'
on run argv
set taskName to item 1 of argv
tell application "Things3"
set matchingTodos to to dos of list "Today" whose name contains taskName
if (count of matchingTodos) = 0 then
error "No task found matching: " & taskName
end if
set targetTodo to first item of matchingTodos
set cancellation date of targetTodo to (current date)
return "Cancelled: " & name of targetTodo
end tell
end run
EOF
;;
delete|remove)
task_name="$1"
if [[ -z "$task_name" ]]; then
echo "Usage: things delete <task>" >&2
exit 1
fi
osascript - "$task_name" <<'EOF'
on run argv
set taskName to item 1 of argv
tell application "Things3"
set matchingTodos to to dos of list "Today" whose name contains taskName
if (count of matchingTodos) = 0 then
error "No task found matching: " & taskName
end if
set targetTodo to first item of matchingTodos
set taskNameToDelete to name of targetTodo
delete targetTodo
return "Deleted: " & taskNameToDelete
end tell
end run
EOF
;;
reschedule|move)
task_name="$1"
when="${2:-tomorrow}"
if [[ -z "$task_name" ]]; then
echo "Usage: things reschedule <task> [when]" >&2
echo " when: today, tomorrow, someday, +N (days from now)" >&2
exit 1
fi
osascript - "$task_name" "$when" <<'EOF'
on run argv
set taskName to item 1 of argv
set whenStr to item 2 of argv
tell application "Things3"
set matchingTodos to to dos of list "Today" whose name contains taskName
if (count of matchingTodos) = 0 then
error "No task found matching: " & taskName
end if
set targetTodo to first item of matchingTodos
-- Parse the when parameter
if whenStr is "today" then
set targetDate to (current date)
else if whenStr is "tomorrow" then
set targetDate to (current date) + (1 * days)
else if whenStr is "someday" then
-- Move to Someday list (unschedule)
move targetTodo to list "Someday"
return "Moved to Someday: " & name of targetTodo
else if whenStr starts with "+" then
set daysToAdd to (text 2 thru -1 of whenStr) as integer
set targetDate to (current date) + (daysToAdd * days)
else
error "Invalid date format. Use: today, tomorrow, someday, or +N"
end if
schedule targetTodo for targetDate
return "Rescheduled: " & name of targetTodo
end tell
end run
EOF
;;
*)
echo "Unknown command: $cmd" >&2
echo "Usage:" >&2
echo " things today - List today's tasks" >&2
echo " things add <task> [tags] [notes] - Add task to today" >&2
echo " things complete <task> - Mark task as complete" >&2
echo " things cancel <task> - Mark task as cancelled" >&2
echo " things delete <task> - Delete task" >&2
echo " things reschedule <task> <date> - Move task (today|tomorrow|someday|+N)" >&2
exit 1
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment