Documentation
¶
Overview ¶
Package things3 provides read-only access to the Things 3 macOS application's SQLite database.
This package is a Go port of the Python things.py library, offering full API parity for querying tasks, projects, areas, and tags from the Things 3 app.
Basic Usage ¶
Create a client and query tasks:
client, err := things3.New()
if err != nil {
log.Fatal(err)
}
defer client.Close()
// Get inbox tasks
inbox, err := client.Inbox(ctx)
// Get all incomplete to-dos
todos, err := client.Todos(ctx)
Query Builder ¶
For complex queries, use the fluent query builder:
tasks, err := client.Tasks().
WithType(things3.TaskTypeTodo).
WithStatus(things3.StatusIncomplete).
InProject("project-uuid").
WithDeadline(things3.DateOpExists).
All(ctx)
Configuration ¶
Configure the client with functional options:
// Use custom database path
client, err := things3.New(things3.WithDatabasePath("/path/to/main.sqlite"))
// Enable SQL query logging
client, err := things3.New(things3.WithPrintSQL(true))
Database Discovery ¶
The database path is discovered in the following order:
- Custom path provided via WithDatabasePath option
- THINGSDB environment variable
- Auto-discovery of default Things 3 database location
Type System ¶
The package uses integer-based enums that map directly to database values:
- TaskType: TaskTypeTodo (0), TaskTypeProject (1), TaskTypeHeading (2)
- Status: StatusIncomplete (0), StatusCanceled (2), StatusCompleted (3)
- StartBucket: StartInbox (0), StartAnytime (1), StartSomeday (2)
Index ¶
- Variables
- type Area
- type AreaQuery
- func (q *AreaQuery) All(ctx context.Context) ([]Area, error)
- func (q *AreaQuery) Count(ctx context.Context) (int, error)
- func (q *AreaQuery) First(ctx context.Context) (*Area, error)
- func (q *AreaQuery) IncludeItems(include bool) *AreaQuery
- func (q *AreaQuery) WithTag(tag any) *AreaQuery
- func (q *AreaQuery) WithUUID(uuid string) *AreaQuery
- type ChecklistItem
- type Client
- func (c *Client) AddProjectURL(params map[string]string) string
- func (c *Client) AddTodoURL(params map[string]string) string
- func (c *Client) Anytime(ctx context.Context) ([]Task, error)
- func (c *Client) Areas() *AreaQuery
- func (c *Client) Canceled(ctx context.Context) ([]Task, error)
- func (c *Client) ChecklistItems(ctx context.Context, todoUUID string) ([]ChecklistItem, error)
- func (c *Client) Close() error
- func (c *Client) Complete(ctx context.Context, uuid string) error
- func (c *Client) Completed(ctx context.Context) ([]Task, error)
- func (c *Client) Deadlines(ctx context.Context) ([]Task, error)
- func (c *Client) Filepath() string
- func (c *Client) Get(ctx context.Context, uuid string) (any, error)
- func (c *Client) Inbox(ctx context.Context) ([]Task, error)
- func (c *Client) Last(ctx context.Context, offset string) ([]Task, error)
- func (c *Client) Link(uuid string) string
- func (c *Client) Logbook(ctx context.Context) ([]Task, error)
- func (c *Client) OpenSearch(ctx context.Context, query string) error
- func (c *Client) Projects(ctx context.Context) ([]Task, error)
- func (c *Client) Search(ctx context.Context, query string) ([]Task, error)
- func (c *Client) SearchURL(query string) string
- func (c *Client) Show(ctx context.Context, uuid string) error
- func (c *Client) ShowURL(uuid string) string
- func (c *Client) Someday(ctx context.Context) ([]Task, error)
- func (c *Client) Tags() *TagQuery
- func (c *Client) Tasks() *TaskQuery
- func (c *Client) Today(ctx context.Context) ([]Task, error)
- func (c *Client) Todos(ctx context.Context) ([]Task, error)
- func (c *Client) Token(ctx context.Context) (string, error)
- func (c *Client) Trash(ctx context.Context) ([]Task, error)
- func (c *Client) URL(ctx context.Context, cmd URLCommand, params map[string]string) (string, error)
- func (c *Client) Upcoming(ctx context.Context) ([]Task, error)
- type Option
- type StartBucket
- type Status
- type Tag
- type TagQuery
- type Task
- type TaskQuery
- func (q *TaskQuery) All(ctx context.Context) ([]Task, error)
- func (q *TaskQuery) ContextTrashed(trashed bool) *TaskQuery
- func (q *TaskQuery) Count(ctx context.Context) (int, error)
- func (q *TaskQuery) First(ctx context.Context) (*Task, error)
- func (q *TaskQuery) InArea(area any) *TaskQuery
- func (q *TaskQuery) InHeading(heading any) *TaskQuery
- func (q *TaskQuery) InProject(project any) *TaskQuery
- func (q *TaskQuery) IncludeItems(include bool) *TaskQuery
- func (q *TaskQuery) Last(offset string) *TaskQuery
- func (q *TaskQuery) OrderByTodayIndex() *TaskQuery
- func (q *TaskQuery) Search(query string) *TaskQuery
- func (q *TaskQuery) Trashed(trashed bool) *TaskQuery
- func (q *TaskQuery) WithDeadline(deadline any) *TaskQuery
- func (q *TaskQuery) WithDeadlineSuppressed(suppressed bool) *TaskQuery
- func (q *TaskQuery) WithStart(s StartBucket) *TaskQuery
- func (q *TaskQuery) WithStartDate(date any) *TaskQuery
- func (q *TaskQuery) WithStatus(s Status) *TaskQuery
- func (q *TaskQuery) WithStopDate(date any) *TaskQuery
- func (q *TaskQuery) WithTag(tag any) *TaskQuery
- func (q *TaskQuery) WithType(t TaskType) *TaskQuery
- func (q *TaskQuery) WithUUID(uuid string) *TaskQuery
- type TaskType
- type URLCommand
Constants ¶
This section is empty.
Variables ¶
var ( // ErrDatabaseNotFound is returned when the Things database cannot be located. ErrDatabaseNotFound = errors.New("things3: database not found") // ErrTaskNotFound is returned when a task with the specified UUID does not exist. ErrTaskNotFound = errors.New("things3: task not found") // ErrAreaNotFound is returned when an area with the specified UUID does not exist. ErrAreaNotFound = errors.New("things3: area not found") // ErrTagNotFound is returned when a tag with the specified title does not exist. ErrTagNotFound = errors.New("things3: tag not found") // ErrInvalidParameter is returned when an invalid parameter value is provided. ErrInvalidParameter = errors.New("things3: invalid parameter") // ErrDatabaseVersionTooOld is returned when the database version is not supported. ErrDatabaseVersionTooOld = errors.New("things3: database version too old (requires version > 21)") // ErrAuthTokenNotFound is returned when the URL scheme auth token cannot be read. ErrAuthTokenNotFound = errors.New("things3: auth token not found") )
Functions ¶
This section is empty.
Types ¶
type Area ¶
type Area struct {
UUID string `json:"uuid"`
Type string `json:"type"` // Always "area"
Title string `json:"title"`
// Nested items (populated when include_items=true)
Tags []string `json:"tags,omitempty"`
Items []Task `json:"items,omitempty"`
}
Area represents an area in Things 3.
type AreaQuery ¶
type AreaQuery struct {
// contains filtered or unexported fields
}
AreaQuery provides a fluent interface for building area queries.
func (*AreaQuery) IncludeItems ¶
IncludeItems includes tasks in each area.
type ChecklistItem ¶
type ChecklistItem struct {
UUID string `json:"uuid"`
Type string `json:"type"` // Always "checklist-item"
Title string `json:"title"`
Status string `json:"status"` // "incomplete", "completed", or "canceled"
StopDate *time.Time `json:"stop_date,omitempty"`
Created time.Time `json:"created"`
Modified time.Time `json:"modified"`
}
ChecklistItem represents a checklist item within a to-do.
func (*ChecklistItem) IsCanceled ¶
func (c *ChecklistItem) IsCanceled() bool
IsCanceled returns true if the checklist item is canceled.
func (*ChecklistItem) IsCompleted ¶
func (c *ChecklistItem) IsCompleted() bool
IsCompleted returns true if the checklist item is completed.
func (*ChecklistItem) IsIncomplete ¶
func (c *ChecklistItem) IsIncomplete() bool
IsIncomplete returns true if the checklist item is incomplete.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client provides read-only access to the Things 3 database.
func New ¶
New creates a new Things 3 client. Options can be provided to configure the client behavior.
func (*Client) AddProjectURL ¶
AddProjectURL returns a URL to add a new project with the given parameters.
func (*Client) AddTodoURL ¶
AddTodoURL returns a URL to add a new to-do with the given parameters.
func (*Client) ChecklistItems ¶
ChecklistItems returns the checklist items for a to-do.
func (*Client) Complete ¶
Complete marks a task as complete using the Things URL scheme. Requires the URL scheme authentication token to be set in Things.
func (*Client) Get ¶
Get retrieves an object by UUID. Returns a Task, Area, or Tag depending on what is found. Returns nil if not found.
func (*Client) Last ¶
Last returns tasks created within the last X days/weeks/years. Format: "3d" (3 days), "2w" (2 weeks), "1y" (1 year).
func (*Client) Link ¶
Link returns a things:// URL that shows the item. Alias for ShowURL for backwards compatibility.
func (*Client) OpenSearch ¶
OpenSearch opens Things and performs a search for the given query.
func (*Client) Search ¶
Search searches for tasks matching the query. Searches in task title, notes, and area title.
func (*Client) Today ¶
Today returns tasks that would appear in Today view. This includes: - Tasks with a start date set to today or earlier and in Anytime - Scheduled tasks from Someday with past start dates (yellow dot tasks) - Overdue tasks with deadlines that haven't been suppressed
func (*Client) URL ¶
URL builds a Things URL scheme URL. See https://culturedcode.com/things/help/url-scheme/ for details.
type Option ¶
type Option func(*clientOptions)
Option is a functional option for configuring the Client.
func WithDatabasePath ¶
WithDatabasePath sets a custom path to the Things database. If not set, the database path is discovered automatically.
func WithPrintSQL ¶
WithPrintSQL enables SQL query logging to stdout. Useful for debugging and understanding the queries being executed.
type StartBucket ¶
type StartBucket int
StartBucket represents the scheduling bucket for a task.
const ( // StartInbox indicates the task is in the Inbox. StartInbox StartBucket = 0 // StartAnytime indicates the task is scheduled for Anytime. StartAnytime StartBucket = 1 // StartSomeday indicates the task is scheduled for Someday. StartSomeday StartBucket = 2 )
func (StartBucket) String ¶
func (s StartBucket) String() string
String returns the string representation of the StartBucket.
type Status ¶
type Status int
Status represents the completion status of a task.
func (Status) IsClosed ¶
IsClosed returns true if the status indicates a closed (completed or canceled) task.
type Tag ¶
type Tag struct {
UUID string `json:"uuid"`
Type string `json:"type"` // Always "tag"
Title string `json:"title"`
Shortcut string `json:"shortcut,omitempty"`
// Nested items (populated when include_items=true)
Items []any `json:"items,omitempty"` // Can contain Area or Task
}
Tag represents a tag in Things 3.
type TagQuery ¶
type TagQuery struct {
// contains filtered or unexported fields
}
TagQuery provides a fluent interface for building tag queries.
func (*TagQuery) IncludeItems ¶
IncludeItems includes areas and tasks for each tag.
type Task ¶
type Task struct {
UUID string `json:"uuid"`
Type TaskType `json:"type"`
Title string `json:"title"`
Status Status `json:"status"`
Notes string `json:"notes,omitempty"`
Start string `json:"start,omitempty"` // "Inbox", "Anytime", or "Someday"
// Trashed indicates whether the task is in the trash.
Trashed bool `json:"trashed,omitempty"`
// Relationships
AreaUUID *string `json:"area,omitempty"`
AreaTitle *string `json:"area_title,omitempty"`
ProjectUUID *string `json:"project,omitempty"`
ProjectTitle *string `json:"project_title,omitempty"`
HeadingUUID *string `json:"heading,omitempty"`
HeadingTitle *string `json:"heading_title,omitempty"`
// Dates
StartDate *string `json:"start_date,omitempty"` // ISO 8601 date
Deadline *string `json:"deadline,omitempty"` // ISO 8601 date
ReminderTime *string `json:"reminder_time,omitempty"` // HH:MM format
StopDate *time.Time `json:"stop_date,omitempty"` // Completion/cancellation date
Created time.Time `json:"created"`
Modified time.Time `json:"modified"`
// Index values for ordering
Index int `json:"index"`
TodayIndex int `json:"today_index"`
// Nested items (populated when include_items=true)
Tags []string `json:"tags,omitempty"`
Checklist []ChecklistItem `json:"checklist,omitempty"`
Items []Task `json:"items,omitempty"` // For projects and headings
}
Task represents a task in Things 3, which can be a to-do, project, or heading.
func (*Task) HasChecklist ¶
HasChecklist returns true if the task has a checklist.
func (*Task) IsCanceled ¶
IsCanceled returns true if the task status is canceled.
func (*Task) IsCompleted ¶
IsCompleted returns true if the task status is completed.
func (*Task) IsIncomplete ¶
IsIncomplete returns true if the task status is incomplete.
type TaskQuery ¶
type TaskQuery struct {
// contains filtered or unexported fields
}
TaskQuery provides a fluent interface for building task queries.
func (*TaskQuery) ContextTrashed ¶
ContextTrashed filters tasks by the trash status of their context (project/heading).
func (*TaskQuery) InArea ¶
InArea filters tasks by area. Pass a UUID string to filter by specific area. Pass true to include only tasks with an area. Pass false to include only tasks without an area.
func (*TaskQuery) InHeading ¶
InHeading filters tasks by heading. Pass a UUID string to filter by specific heading. Pass true to include only tasks with a heading. Pass false to include only tasks without a heading.
func (*TaskQuery) InProject ¶
InProject filters tasks by project. Pass a UUID string to filter by specific project. Pass true to include only tasks with a project. Pass false to include only tasks without a project.
func (*TaskQuery) IncludeItems ¶
IncludeItems includes nested items (checklist for to-dos, tasks for projects/headings).
func (*TaskQuery) Last ¶
Last filters tasks created within the last X days/weeks/years. Format: "3d" (3 days), "2w" (2 weeks), "1y" (1 year).
func (*TaskQuery) OrderByTodayIndex ¶
OrderByTodayIndex orders results by today index instead of default index.
func (*TaskQuery) Search ¶
Search filters tasks by a search query. Searches in task title, notes, and area title.
func (*TaskQuery) Trashed ¶
Trashed filters tasks by trash status. Pass true to include only trashed tasks. Pass false to include only non-trashed tasks.
func (*TaskQuery) WithDeadline ¶
WithDeadline filters tasks by deadline. Accepts: bool (has/doesn't have), "future", "past", or ISO date with optional operator.
func (*TaskQuery) WithDeadlineSuppressed ¶
WithDeadlineSuppressed filters tasks by deadline suppression status.
func (*TaskQuery) WithStart ¶
func (q *TaskQuery) WithStart(s StartBucket) *TaskQuery
WithStart filters tasks by start bucket (Inbox, Anytime, Someday).
func (*TaskQuery) WithStartDate ¶
WithStartDate filters tasks by start date. Accepts: bool (has/doesn't have), "future", "past", or ISO date with optional operator.
func (*TaskQuery) WithStatus ¶
WithStatus filters tasks by status.
func (*TaskQuery) WithStopDate ¶
WithStopDate filters tasks by stop date (completion/cancellation date). Accepts: bool (has/doesn't have), "future", "past", or ISO date with optional operator.
func (*TaskQuery) WithTag ¶
WithTag filters tasks by tag. Pass a tag title to filter by specific tag. Pass true to include only tasks with tags. Pass false to include only tasks without tags.
type TaskType ¶
type TaskType int
TaskType represents the type of a task in Things 3. Tasks can be to-dos, projects, or headings within projects.
type URLCommand ¶
type URLCommand string
URLCommand represents Things URL scheme commands.
const ( // URLCommandShow opens and shows an item. URLCommandShow URLCommand = "show" // URLCommandAdd creates a new to-do. URLCommandAdd URLCommand = "add" // URLCommandAddProject creates a new project. URLCommandAddProject URLCommand = "add-project" // URLCommandUpdate updates an existing item. URLCommandUpdate URLCommand = "update" // URLCommandUpdateProject updates an existing project. URLCommandUpdateProject URLCommand = "update-project" // URLCommandSearch performs a search. URLCommandSearch URLCommand = "search" )
func (URLCommand) String ¶
func (u URLCommand) String() string
String returns the string representation of the URLCommand.