Skip to content

feat(output)!: print a default field set on -j listings, with --fields all for the full record - #454

Merged
ryanlewis merged 4 commits into
mainfrom
feat/json-default-fields
Oct 10, 2026
Merged

ryanlewis merged 4 commits into
mainfrom
feat/json-default-fields

Conversation

@ryanlewis

@ryanlewis ryanlewis commented Oct 10, 2026 •

Copy link
Copy Markdown
Owner

Behaviour change

-j on a task listing (every view, filtered list), search and projects no longer prints every key. Without --fields it prints a default set per kind; --fields all prints the full record, byte-identical to the old -j output. A script that reads notes, projectUUID, areaUUID, headingUUID, creationDate, index, todayIndex or trashed off a task listing, or startBucket off a projects row, needs --fields all (or things show <uuid> -j). show -j is unchanged.

Default sets

Defined next to TaskFields/ProjectFields in internal/output/fields.go, in record order.

  • Tasks: uuid, title, type, status, start, startBucket, startDate, reminderTime, deadline, stopDate, projectTitle, projectTrashed, areaTitle, headingTitle, tags, repeating, checklistProgress
  • Projects: uuid, title, status, start, startDate, deadline, areaTitle, tags, taskCount, openCount

Left out of tasks:

  • notes: the bulk of the output (about half of a full listing); an agent reads them for the one item it acts on, with show.
  • projectUUID, areaUUID, headingUUID: an agent acts on the item's own uuid; it filters by project or area with --project/--area, which take titles.
  • creationDate: rarely used to choose an item; available with --fields.
  • index, todayIndex: Things' internal sort keys; the listing is already in the app's order.
  • trashed: always false outside the trash view, always true inside it.

startBucket stays in: it is how today -j tells the app's This Evening rows apart, and matching what Things.app shows is the project's goal.

projectTrashed stays in: it is omitempty, so it costs nothing on ordinary rows, and on --project <trashed project> it tells an agent the row will be refused before it tries a write.

Left out of projects: startBucket (a project's This Evening placement only matters inside a today listing, which carries it) and areaUUID (as above). taskCount stays in, because the docs' own "projects with nothing left open" recipe uses it.

all

--fields all on its own prints the full record. all with other names (all,notes) is refused with a plain error, since all already names them. No JSON key is named all, and a test keeps it that way.

Small fixes

  • The unknown-field and empty-list messages now end with ", or all for the full record".
  • An empty --fields ("", " , ") now gets the unknown field payload with valid and no unknown, instead of the generic error token.
  • docs/content/commands.md hard-codes the key lists, so a new test (internal/output/docs_test.go) ties them, and the default sets in commands.md and SKILL.md, to the variables.

Sizes

On a copy of today's Things backup DB, old -j vs new -j (bytes):

listing before after
anytime -a "Personal Projects" (94 tasks) 90150 28583
today 53979 16542
upcoming 23020 8030
deadlines 8774 3462
search the 851978 270356
logbook 778483 355580
projects 5857 4577

--fields all matched the old -j byte for byte on every listing above (also inbox, someday, trash, repeating, projects --completed, list --project). Wall time for logbook -j is unchanged (~25 ms).

Docs

SKILL.md, docs/content/commands.md, docs/content/agents.md and the README output paragraph are updated. docs/content/changelog.md is generated from release notes, so it is not edited.

…s all for the full record

Without --fields, a JSON task listing, search and projects now print the
keys an agent needs to pick an item and act on it. Notes, the parent
uuids, creationDate and Things' bookkeeping need --fields all or show.
An empty --fields gets the unknown field payload with the valid names.

BREAKING CHANGE: -j on listings no longer prints every key; pass
--fields all for the previous output.
@ryanlewis
ryanlewis force-pushed the feat/json-default-fields branch from 8e18ecf to fe7344d Compare October 10, 2026 14:29
@ryanlewis
ryanlewis merged commit aab9314 into main Oct 10, 2026
10 checks passed
@ryanlewis
ryanlewis deleted the feat/json-default-fields branch October 10, 2026 14:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant