Docs
Reference

Changelog

What changed in each release, newest first. These are the release notes published with each version on GitHub, where the downloads are.

v0.9.0

· Downloads on GitHub

things-cli v0.9.0 — edits confirm what happened

things edit and things project edit used to exit 0 with no output, so an agent had to run things show to learn whether the change had landed. They now wait for Things to record the write and print the item, in the same form as things show, so one call does both. How long the CLI waits for that confirmation can now be configured. Two behaviour changes, below.

Behaviour changes

  • edit and project edit print the edited item. The output is the same as things show for that item, plain or --json. Anything that expected these commands to print nothing needs updating. (#280)
  • An edit Things drops now fails. The CLI waits for the item’s modification date to change and exits non-zero with edit did not apply: … if it never does. Before, a dropped edit reported success. An edit that only re-sets values the item already has is caught before the wait when it uses --title, --notes, --tags, --add-tags or a --deadline date. Any other flag, --when included, still waits and reports the same error, because Things does not record a no-op as a change. The error says to check with things show <uuid> before retrying. (#280)

Also

  • --no-verify and --duplicate edits print a line saying the edit was sent but not confirmed, with "confirmed": false and a reason under --json, rather than printing nothing. (#280)
  • The read-back wait is configurable, with --verify-timeout or the verify_timeout config key, and defaults to 5s. It applies to every write that is read back: complete, cancel, edit, project edit, import and tag add. In v0.8.0, complete, cancel, import and tag add waited 10s before reporting a change as not applied; they now give up after 5s unless configured otherwise. (#281)
  • The bundled skill tells agents that exit 0 with the item printed means the edit is confirmed, and to put several changes to one item in a single edit. Run things skill install after upgrading. (#280, #281)

Requirements

macOS with Things3 installed. Binaries for Apple Silicon (darwin_arm64) and Intel (darwin_amd64).


What’s Changed

Other Changes

Full Changelog: https://github.com/ryanlewis/things-cli/compare/v0.8.0...v0.9.0

v0.8.0

· Downloads on GitHub

things-cli v0.8.0 — parity with the app’s lists

Every list in Things.app now has a CLI view that returns the same rows in the same order, projects included. Until now a project scheduled for Today was visible in the app and absent from things today, so an agent driving the CLI never saw it. Every view was measured against the app’s own lists by uuid, and every one of them now matches. Two JSON fields became words, listings are deterministic, agents are steered to UUIDs, and the code behind the views was reorganised so the next parity fix is one table entry. Two breaking changes, below.

Breaking changes: type and start are strings

type and start on task rows in every --json output were Things’ internal integers. They are now words, so a caller can tell a project from a task, or a deferred item from a scheduled one, without a lookup table. Anything matching on type == 1 or start == 2 must change. On input, the legacy integers are still accepted. start also appears on things projects -j rows. (#208, #214, #218, #223, #241, #251)

BeforeAfter
"type": 0"type": "task"
"type": 1"type": "project"
"type": 2"type": "heading" (never returned by any command)
"start": 0"start": "inbox"
"start": 1"start": "anytime" (Today when it carries a date)
"start": 2"start": "someday" (Upcoming when it carries a date)

The word for a to-do is task everywhere the CLI speaks, in JSON values, error payloads, the agent brief and the docs. The one exception is the things import payload, which keeps Things’ own spelling to-do. Run things skill install after upgrading so agents pick up the new skill, which documents all of this.

Projects appear where the app shows them

  • today, upcoming, someday, logbook, trash and deadlines include projects. A project scheduled, deferred, closed, trashed or due is a row with "type": "project" in JSON and a (project) marker in plain text. anytime is the exception, as in the app: it lists a project’s tasks under the project as a group header rather than as a row. The bare --area and --tag listings include projects too; --project X never matches a project itself. (#201, #205, #206, #209, #212, #216, #213, #220, #217, #236, #222, #232)
  • logbook includes cancelled items, with status telling them apart. (#210, #225)
  • logbook and trash fold a closed or trashed project’s tasks into the project’s row, as the app does; the same fold applies under --include-completed. Ask for the project instead: things --project <uuid> on a closed project returns its tasks whatever their status, and things show <uuid> --agent lists them with their real status marks instead of claiming the project has no open tasks. Logbook went from 1334 rows to the app’s 910 on the author’s data, row for row. (#229, #235, #249, #252, #253, #260)
  • Closed items file by calendar day. An item you close stays in Today and Anytime, struck through in the app, until midnight, then moves to the logbook. things today --include-completed and the new things anytime --include-completed show them until then; --include-completed used to keep everything closed since the last “Log Completed Now”. (#230, #233, #238, #247)
  • someday no longer surfaces tasks that live inside a project. The app keeps a deferred task inside its project, whichever list the project is in; measured with a probe project created and deleted through the app. things someday --project X is now rejected like the other impossible filters. (#211, #228)
  • Naming a trashed project with --project <uuid> reaches its contents in every view. The app returns a trashed project’s untrashed children when asked for them directly, and so does the CLI now, in today, anytime, logbook and the rest, not only in the bare things --project form. Trash keeps its fold, so a task trashed on its own account inside a later-trashed project stays where the app keeps it. (#263, #273)
  • Repeating templates, headings and trashed items stay excluded from these views exactly as before.

Listings are ordered as the app orders them, and deterministically

  • today, anytime and someday arrange rows as the app does: unfiled items first, then areas in area order, and inside an area its own tasks before those of its projects. upcoming is ordered by start date. Closed items shown under --include-completed stay where they were rather than sinking to the end. (#217, #236, #237, #239)
  • Every view, search and lookup ordering ends in a total tiebreak, so the same list run twice numbers the same items the same way and things complete 3 acts on the row you read. Deadlines and logbook had no tiebreak at all. Numbers still move as items are added, closed or rescheduled. (#221, #226)

Agents: use UUIDs, and --json no longer touches the row cache

  • A --json listing no longer writes the numbered-row cache. JSON output never showed row numbers, so a JSON listing could only move the numbers a person had just read, and two agents on one machine could race each other into completing the wrong task. Numeric references keep resolving against the last plain-text listing. The bundled skill and https://things.rlew.io/agents/ now tell agents to use --json and act on uuid, never on row numbers, with every example resolving a UUID first. Thanks to @davidolrik for the report. (#246, #261)
  • things skill install honours each agent’s config-directory variable: $CLAUDE_CONFIG_DIR for Claude Code (thanks to @davidolrik for the fix), $CODEX_HOME for Codex and $PI_CODING_AGENT_DIR for Pi, each with that tool’s own rule for tilde expansion. (#227, #234, #250, #254)
  • things projects -j reports start, startDate and deadline, and its taskCount and openCount are documented, with a recipe for finding projects with no open tasks and the caveats that go with it. (#202, #204, #203, #207)
  • References and filters match literally. A task reference, a search query and the --project, --area and --tag filters used to be SQL LIKE patterns, so things complete '20_30 review' could resolve to and complete 20:30 review, and things search '50%' matched everything. % and _ are now characters to find. (#262, #266, #267, #268)
  • Row numbers expire after four hours. The numbered-row cache now records when the listing ran and which command printed it, and a bare number against a listing older than four hours is refused with an error that names the listing to re-run, or the UUID to use instead, under the stable token stale list cache. A cache written by an older release counts as stale, so the first numeric reference after upgrading asks for a fresh listing. (#265, #271)
  • A title shared by a project and a task is an ambiguity, not a coin toss. things project edit Chores used to resolve the first row with that title, land on the task and recommend a retry that edited the wrong item. An exact title that matches more than one open item now returns the existing ambiguous task error listing each candidate with its type and UUID, so the caller picks by UUID. (#194, #270)
  • The jq select examples in the agent docs were missing .[] | and failed against the JSON array; all are fixed. (#225)

Under the hood

Each list view is now described once, in one table, with a golden test that pins the exact SQL for every view, filter and flag combination; the four copies of the column renderer became one; main.go was split by command group; the status, type and start codecs share one implementation. None of this changes output: it was verified byte for byte against the previous binary across hundreds of live invocations. (#240, #242, #243, #248, #258, #259, #264)

Also

  • edit and project edit refuse the wrong kind of reference with the same structured error instead of opening a things:///update URL for the wrong kind of item. (#190, #193, #219, #231)
  • An empty listing that names a repeating project template says so. things --project <template> prints a one-line note on stderr that the template’s tasks are not listed, instead of an unexplained empty result. (#174, #272)
  • The reference site at https://things.rlew.io moved to Hugo with a new landing page, an agents page, a social preview image and analytics, and rebuilds on each release. Local builds stamp version, commit and date. (#183, #185, #186, #188, #192, #195, #198)

Requirements

macOS with Things3 installed. Binaries for Apple Silicon (darwin_arm64) and Intel (darwin_amd64).


What’s Changed

Other Changes

New Contributors

Full Changelog: https://github.com/ryanlewis/things-cli/compare/v0.7.0...v0.8.0

v0.7.0

· Downloads on GitHub

things-cli v0.7.0 — a config file, tag creation, and output an agent can trust

A TOML config file for persistent defaults, tag creation from the CLI, a things show --agent hand-off format, a repeating view, machine-readable --json errors, and fixes to what lookups and views return.

Settings live in a file now

  • ~/.config/things-cli/config.toml supplies defaults for json, color, db, no_verify, strict_tags, create_tags, assume_yes and hints. Flags still win per run. --config PATH or THINGS_CLI_CONFIG point at another file, $XDG_CONFIG_HOME is honoured, and the file is optional: without one, things runs on its built-in defaults. things config path, config show and config init (writes a commented template) round it out. Unknown keys and malformed TOML fail with one line naming the file. Full reference at https://things.rlew.io/configuration/. (#159, #160)
  • assume_yes is scoped to complete and cancel; it cannot reach skill uninstall, whose --yes means delete. (#158, #169)

Tags can be created from the CLI

  • things tag add <name>... creates tags over AppleScript, skipping names that already exist (case-insensitive) and reading the tag list back to confirm. --create-tags on add, edit, project add, project edit and import creates the unknown tags before the write instead of warning. --create-tags with --strict-tags is rejected. Tag names are escaped for AppleScript. (#144, #150)

Handing a to-do to an agent

  • things show <ref> --agent prints a self-contained Markdown brief: the to-do, its notes and checklist, and the exact UUID-based commands to close it out, ready for things show 3 --agent | claude -p "action this". Plain list and search output on a terminal ends with a one-line hint; --no-hints or hints = false turns it off. Notes are fenced and labelled as content so a to-do cannot forge the closing-out section. (#153, #172)
  • --json is now non-interactive and its errors are JSON. An ambiguous or missing ref no longer opens the picker or prints help text to stdout; you get one object with a stable error token (ambiguous task, not found, import refused, import partially applied, or error), the message, the query and the candidates or per-item details. Exit codes match the plain path. (#152, #157, #161, #166, #164, #168)
  • --yes / -y on complete and cancel skips the project confirmation, so things --json complete <project> --yes works from a script. (#158, #169)

Lookups and views return what they claim

  • Project headings never come back as tasks from show, edit, complete, cancel, open, search or the numeric index cache. A heading with the same title as a to-do no longer makes the lookup ambiguous. (#146, #149)
  • Repeating templates have their own view. things repeating lists to-do and project templates (projects marked (project)), and they are gone from someday, the catch-all project view and things projects. Generated instances were never affected and still list in today and upcoming. (#147, #154, #165, #170)
  • A title shared by a template and its generated to-do resolves to the to-do, so things complete "Water plants" no longer hits the repeating refusal while an actionable instance exists. The template is still reachable by UUID or from things repeating. (#156, #163)
  • To-dos under a trashed project are hidden in inbox, today, upcoming, anytime, someday and deadlines, not just the filtered views. trash and logbook still show them. (#155, #162)
  • To-dos inside a repeating project template are hidden from the same views, since the app only shows the generated copies. (#171, #173)
  • import with operation: update goes through the repeating check and the read-back. A payload that sets when, deadline, completed or canceled on a repeating item is refused whole, with the path of each offending item, before anything is sent. Status changes are read back after the write with one shared timeout. completed: false and canceled: false count as status changes, and canceled takes priority over completed, as the Things docs specify. (#145, #151)
  • The things tag add suggestion printed for unknown tags is now shell-quoted, and --json=1, -jv and other flag spellings render parse errors as JSON. (#164, #168)

Also

  • Import checks resolve every item in one query per round instead of one per item. (#167, #175)
  • The bundled agent skill was reorganised and audited against every --help; open is no longer described as a write, and the skill, config and tag commands are covered. Run things skill install again to pick it up. (#176)

Requirements

macOS with Things3 installed. Binaries for Apple Silicon (darwin_arm64) and Intel (darwin_amd64).


What’s Changed

Other Changes

Full Changelog: https://github.com/ryanlewis/things-cli/compare/v0.6.0...v0.7.0

v0.6.0

· Downloads on GitHub

things-cli v0.6.0 — filters that tell the truth, writes that fail loudly

Four fixes from recent use, three of them about the CLI quietly reporting the wrong thing. Two new flags.

Filters no longer under-report

  • --project, --area and --tag now search all open tasks by default instead of the Today view. Naming a project previously returned only its Today slice while the header just printed the project name; one project showed 8 tasks where there were 59. An explicit view still wins and is now labelled in the header when combined with a filter. (#140, #142)
  • Tasks nested under a project heading are included in project and area filters, and show reports their project and area. They were invisible before because Things stores the project on the heading row, not the task. (#139, #142)
  • Tasks left open under a trashed project no longer leak into filtered output.
  • Behaviour change: things today "Chores" now means today within Chores. It used to silently switch to the whole-project view.

Complete and cancel now verify the write landed

  • Repeating to-dos and projects are refused up front. Things silently drops status, when and deadline changes on repeating items through both the URL scheme and AppleScript, so cancel used to exit 0 and change nothing. The CLI now checks for a recurrence rule and refuses with a message naming the blocked attributes. show prints a Repeats: line and JSON carries "repeating": true. (#129, #143)
  • Every complete and cancel reads the status back from the database and exits non-zero if it did not change. A new global --no-verify skips the check. edit --complete --cancel together is now rejected. (#143)

Unknown tags are no longer dropped silently

  • Things ignores tags that do not already exist. add, edit, project add, project edit and import now warn on stderr for each unknown tag, and --strict-tags refuses to write at all. Matching is case-insensitive, as Things treats tag names. Creating tags from the CLI is still open as #144. (#102, #141)

Also

  • Dependency bumps: modernc sqlite v1.57, kong v1.16.1, lipgloss v2.0.6. (#118)
  • Release pipeline egress allowlist narrowed to the Apple notary bucket. (#138)

Requirements

macOS with Things3 installed. Binaries for Apple Silicon (darwin_arm64) and Intel (darwin_amd64).


What’s Changed

📦 Dependencies

Other Changes

Full Changelog: https://github.com/ryanlewis/things-cli/compare/v0.5.3...v0.6.0

v0.5.3

· Downloads on GitHub

things-cli v0.5.3 — signed and notarized binaries

Infra release: no CLI changes. The binaries themselves are the feature.

Release pipeline

  • Darwin binaries are now Developer ID–signed and notarized by Apple. Both architectures are signed and notarized before archiving, so the tarballs, checksums, and provenance attestations all cover the signed Mach-O. Gatekeeper accepts the binary without any quarantine workaround — the cask’s xattr -d com.apple.quarantine hack is gone. (#130)
  • Release job egress is now blocked by default with an explicit endpoint allowlist (previously audit-only), limiting what a compromised dependency or action could exfiltrate — the job holds signing keys now. (#130)

One caveat: bare Mach-O binaries can’t have the notarization ticket stapled, so Gatekeeper does an online check on first run. Fine for normal installs; only bites a fully-offline first run.

Requirements

macOS with Things3 installed. Binaries for Apple Silicon (darwin_arm64) and Intel (darwin_amd64).


What’s Changed

Other Changes

Full Changelog: https://github.com/ryanlewis/things-cli/compare/v0.5.2...v0.5.3

v0.5.2

· Downloads on GitHub

things-cli v0.5.2 — timestamps back from 2057

Patch release: one bug fix.

Fixes

  • creationDate and stopDate are no longer 31 years in the future. Things stores its absolute timestamps (task creation, task and checklist completion) as Unix-epoch seconds, but they were decoded against Apple’s Core Data reference date (2001-01-01) — so a task created on 2026-08-09 reported "creationDate": "2057-08-09T…" in --json output. Anything sorting or filtering on those fields downstream would misbehave. Scheduling fields (startDate, deadline) use a different encoding and were always correct. (#127)

No CLI surface changes — if you parse creationDate/stopDate from --json output, the values are simply right now.

Requirements

macOS with Things3 installed. Binaries for Apple Silicon (darwin_arm64) and Intel (darwin_amd64).


What’s Changed

Other Changes

Full Changelog: https://github.com/ryanlewis/things-cli/compare/v0.5.1...v0.5.2

v0.5.1

· Downloads on GitHub

things-cli v0.5.1 — cancel projects, honest empty JSON

Patch release: two bug fixes with a supply-chain hardening pass riding underneath.

Fixes

  • things cancel now works on projects. It previously routed every reference through the task-only AppleScript path, so cancelling a project failed with a raw osascript error. Projects now cancel properly, behind the same interactive confirmation complete uses — cancelling a project cascades to its tasks. (#125)
  • Empty --json results emit [], not null. All list-shaped commands (list, search, projects, areas, tags) returned null for an empty result, which breaks jq '.[]' pipelines — including the ones documented in the bundled agent skill. (#124)
  • Date filters on someday are rejected instead of silently matching nothing. Someday items have no start date, so --on/--from/--to could never match; the CLI now says so instead of returning empty output, and the README no longer advertises the impossible combination. (#124)

Small improvements

  • show, complete, and cancel help text now documents the numeric-index reference form (things list today; things complete 3) — it always worked, but only edit admitted it. (#125)
  • things projects gains the -a short flag for --area, matching list and open. (#125)

Supply chain

  • Release artifacts now carry build provenance attestations. install.sh verifies them automatically when the GitHub CLI is present (and refuses to install on a failed verification); check any artifact yourself with gh attestation verify things_<version>_darwin_arm64.tar.gz -R ryanlewis/things-cli. (#122, #123)
  • CI hardening: govulncheck (gating + weekly Security-tab scan), CodeQL, dependency review, and a locked-down release pipeline. (#122)

Requirements

macOS with Things3 installed. Binaries for Apple Silicon (darwin_arm64) and Intel (darwin_amd64).


What’s Changed

📦 Dependencies

Other Changes

Full Changelog: https://github.com/ryanlewis/things-cli/compare/v0.5.0...v0.5.1

v0.5.0

· Downloads on GitHub

things-cli v0.5.0 — clearer JSON status, leaner today

Minor release. Two behaviour changes worth a look before you upgrade any automation, plus dependency maintenance.

Behaviour changes

  • JSON status is now a string. Task, Project, and ChecklistItem status fields render as "open" / "cancelled" / "completed" in JSON instead of the raw Things integers (0 / 2 / 3). The bare ints were an implementation detail that read like a rank. Plain-text output is unchanged. The decoder still accepts both the string name and the legacy integer, and any unrecognised code round-trips as its number — but consumers that parse our JSON status as a number will need to read it as a string. (#107, closes #105)
  • things today excludes completed tasks by default. It now returns only open tasks; completed/cancelled items Things still shows in Today are available behind a new --include-completed flag (UI-parity). For automation, “in today” now means “still to do”. (#109, closes #106)

Maintenance

  • Bumped lipgloss, golang.org/x/term, golang.org/x/sys, and modernc.org/sqlite; actions/checkout → v7 in CI. (#100, #108)

Requirements

macOS with Things3 installed. Binaries for Apple Silicon (darwin_arm64) and Intel (darwin_amd64).


What’s Changed

📦 Dependencies

Other Changes

Full Changelog: https://github.com/ryanlewis/things-cli/compare/v0.4.2...v0.5.0

v0.4.2

· Downloads on GitHub

things-cli v0.4.2 — fix --when rejecting weekday names

Patch release. things add --when monday was incorrectly rejected with “did you mean today?”. The --when typo detector flags any value within Levenshtein distance 2 of a keyword, and monday is exactly distance 2 from today — so it was mistaken for a typo despite being a valid natural-language date Things accepts.

Fix

  • Weekday names and their abbreviations (monday…sunday, plus mon, tue, wed, thu, fri, sat, sun and common variants) now bypass the typo detector and pass through to Things verbatim. Verified against Things3 that each resolves to the correct upcoming scheduled date.
  • Genuine typos (tommorrow, evning, …) are still rejected as before.

Requirements

macOS with Things3 installed. Binaries for Apple Silicon (darwin_arm64) and Intel (darwin_amd64).


What’s Changed

Other Changes

Full Changelog: https://github.com/ryanlewis/things-cli/compare/v0.4.1...v0.4.2

v0.4.1

· Downloads on GitHub

things-cli v0.4.1 — fix Homebrew completion install

Patch release. v0.4.0 added shell completions, but the Homebrew cask passed the shell name as --shell=bash (Homebrew’s :arg format) while things completions takes the shell as a positional argument. The mismatch made brew install print “Failed to generate … completions” warnings and write no completion files.

Fix

  • The cask now calls things completions bash|zsh|fish with the shell as a bare positional argument (Homebrew’s default when shell_parameter_format is omitted), matching the CLI. brew install / brew upgrade now generates the bash, zsh, and fish completion files as intended.

If you installed v0.4.0 from Homebrew, run brew update && brew reinstall ryanlewis/tap/things to pick up working completions.

Requirements

macOS with Things3 installed. Binaries for Apple Silicon (darwin_arm64) and Intel (darwin_amd64).


What’s Changed

Other Changes

Full Changelog: https://github.com/ryanlewis/things-cli/compare/v0.4.0...v0.4.1

v0.4.0

· Downloads on GitHub

things-cli v0.4.0 — shell completions

things <TAB> now completes subcommands, flags, and enum values in bash, zsh, and fish. Homebrew sets it up for you; everyone else runs one line.

Headline

  • Shell completions for bash, zsh, and fish (#94, #95). The Homebrew cask generates them on install, so brew install ryanlewis/tap/things gives you things <TAB> with no extra steps. On other install paths, load them yourself — source <(things completions bash), source <(things completions zsh), or things completions fish | source. Completions are driven from the live command tree, so they never drift from the CLI: subcommand names, flag names, and enum values like --color auto|always|never.

Under the hood

  • Migrated styling to lipgloss v2 (charm.land/lipgloss/v2) (#93). No visible change to list/show output; JSON (-j) stays script-stable.
  • Routine dependency updates (#83, #91, #92).

Docs

  • The bundled agent skill (things skill show / installed SKILL.md) now spells out every things open flag (-p/-a/-t/-q/--filter/--background) and the edit / project edit prepend/append/checklist/*-id flags instead of trailing ... (#89). Reinstall it (things skill install claude, …codex, …pi) to pick up the new text.

Requirements

macOS with Things3 installed. Binaries for Apple Silicon (darwin_arm64) and Intel (darwin_amd64).


What’s Changed

📦 Dependencies

Other Changes

Full Changelog: https://github.com/ryanlewis/things-cli/compare/v0.3.1...v0.4.0

v0.3.1

· Downloads on GitHub

things-cli v0.3.1 — clean uninstall

Patch release: the Homebrew cask now ships a zap stanza so a full uninstall cleans up after itself.

Change

  • Cask zap trash: now lists ~/Library/Caches/things-cli (the last-list cache that backs things complete 1-style indices), so brew uninstall --zap things leaves no orphan state behind (#86)

Plain brew uninstall things still leaves the cache alone — zap only fires with --zap (or brew zap things separately), so a routine uninstall + reinstall keeps your indices intact.

Requirements

macOS with Things3 installed. Binaries for Apple Silicon (darwin_arm64) and Intel (darwin_amd64).


What’s Changed

Other Changes

Full Changelog: https://github.com/ryanlewis/things-cli/compare/v0.3.0...v0.3.1

v0.3.0

· Downloads on GitHub

things-cli v0.3.0 — Homebrew tap, date filters, polished output

Install with brew install ryanlewis/tap/things and start slicing your lists by date — plus a fresh coat of lipgloss styling on list and show.

Headline

  • Homebrew cask — brew install ryanlewis/tap/things (auto-published from each release into ryanlewis/homebrew-tap)
  • Date-range list filters — narrow any list with --on, --from, and --to (#81)
  • Styled output — list and show now render with lipgloss; JSON output (-j) is unaffected and remains script-stable

Fixes

  • things today keeps completed items visible until you log them, matching the Things app (#74)
  • ThingsDate marshals as YYYY-MM-DD in JSON output (was a packed integer) (#79)

Docs

  • Install page surfaces Homebrew as the recommended option
  • Skill docs cover bulk reschedule, the auth-token flow, and weekday --when parsing (#80)

Requirements

macOS with Things3 installed. Binaries for Apple Silicon (darwin_arm64) and Intel (darwin_amd64).


What’s Changed

📦 Dependencies

Other Changes

Full Changelog: https://github.com/ryanlewis/things-cli/compare/v0.2.0...v0.3.0

v0.2.0

· Downloads on GitHub

things-cli v0.2.0 — more writes, safer writes

A bigger surface area for writing back to Things3, plus client-side validation so the URL scheme can’t silently swallow bad input. The docs now live at things.rlew.io.

New commands

  • things edit — update existing tasks (title, notes, when, deadline, tags, checklist, project, area) via the URL scheme
  • things open — reveal a task, project, or area in the Things3 app
  • things import — batch-create items from a JSON payload using the things:///add-json scheme
  • things project add / things project edit — create and update projects
  • things skill — install the bundled Claude Code skill (also supports Codex and Pi agents) so an AI assistant can drive things-cli correctly

Quality of life

  • --when and --deadline are validated and normalized before being sent to Things
  • URL-scheme size and field limits are checked client-side, with clear errors instead of a silently truncated task
  • things today ordering now matches the Things app (projects and area-only items grouped by area index)
  • --todos / --checklist correctly expand literal \n in arguments

Docs

  • Project site published at things.rlew.io — install guide, command reference, about page
  • README rewritten with grouped command tables and capabilities above the fold

Requirements

macOS with Things3 installed. Binaries for Apple Silicon (darwin_arm64) and Intel (darwin_amd64).


What’s Changed

📦 Dependencies

Other Changes

New Contributors

Full Changelog: https://github.com/ryanlewis/things-cli/compare/v0.1.0...v0.2.0

v0.1.0

· Downloads on GitHub

🎉 First release — things-cli v0.1.0

A command-line interface for Things3 on macOS. Reads tasks, projects, areas and tags directly from the Things3 SQLite database (read-only) and writes via the official things:/// URL scheme and AppleScript — so Things stays the source of truth and your data never leaves the machine.

Highlights

  • Read anything — things today, things inbox, things upcoming, project/area/tag filters, full-text things search, and things show with numeric references into the last list
  • Write safely — things add creates tasks via the Things URL scheme; things complete / things cancel / things log drive Things via AppleScript
  • JSON everywhere — -j on any command emits structured output for piping into jq
  • Pure Go — single static binary, no cgo, no external SQLite dependency (modernc.org/sqlite)
  • Installable three ways
    • curl -fsSL https://raw.githubusercontent.com/ryanlewis/things-cli/main/install.sh | sh (verifies checksums)
    • go install github.com/ryanlewis/things-cli/cmd/things@latest
    • Download a tarball from this release and drop the binary onto your PATH

Requirements

macOS with Things3 installed. Binaries for Apple Silicon (darwin_arm64) and Intel (darwin_amd64).


What’s Changed

📦 Dependencies

New Contributors

Full Changelog: https://github.com/ryanlewis/things-cli/commits/v0.1.0