fix(edit): refuse a project reference instead of opening things:///update - #190
Merged
Merged
Conversation
…date resolveTask returns projects as well as to-dos, so `things edit <project>` reached things.UpdateTask and opened things:///update with a project id. Things answers that with a modal "Cannot update to-do with ID ... because it does not exist", steals focus and changes nothing. edit now refuses a project before any URL is opened, with `"<title>" is a project; use things project edit` and, under --json, a new stable error token `not a task` carrying kind, query, uuid and title. Refusing rather than routing to update-project keeps the task-only flags (checklist, list, heading) from being silently dropped. Closes #189
…citly Follow-up from review: the retry command in the refusal message was derived from Kind, which only reads as a real command for "project"; it is now an explicit field. The README and site command pages describe the refusal where someone reads about editing, not only in the --json error section.
ryanlewis
force-pushed
the
fix/edit-project-guard
branch
from
September 5, 2026 17:33
c365212 to
323c819
Compare
ryanlewis
added a commit
that referenced
this pull request
Sep 5, 2026
…dit (#193) #190 gave `things edit <project>` a stable `not a task` token under `--json`. The opposite mistake did not get the same treatment: `things project edit <to-do>` returned a bare `not a project: <title>`, which lands under `--json` as the generic `{"error": "error"}` with no `kind`, `uuid` or `title`. An agent branching on tokens handled one direction and had to string-match the other. Both guards now return the same error type, carrying the token it renders as — `not a task` one way, `not a project` the other — with `kind`, `query`, `uuid` and `title` in each. The plain-text message mirrors its opposite: ``` Error: "Post letter" is a to-do; use things edit ``` The guard sits before `checkRepeating`, tag verification and any URL open, so nothing is written. A test mirrors the one from #190: a to-do reference through `project edit`, nothing opened, the whole payload asserted. Docs: the new token in `internal/skill/SKILL.md`, the README error section and the site commands page, next to the `not a task` entries. The site's agents page listed tokens too and had never gained `not a task` — it now names both. One thing found and left alone: title resolution has no type preference, so with both a project and a to-do called "Chores", `things project edit Chores` resolves the to-do and points at `things edit`, which is not the item the user meant. That is in `resolveTask`/`GetTask` and predates this change — worth its own issue. Closes #191
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
things edit <project>resolved the reference fine —resolveTaskreturns projects as well as to-dos — and then openedthings:///update?id=<project uuid>. Things answers a project id there with a modal "Cannot update to-do with ID … because it does not exist", steals focus, and changes nothing.editnow refuses a project before any URL is opened. Plain text on stderr:Under
--jsonit is a new stable token,not a task, carryingkind,query,uuidandtitle, so an agent can branch on it and retry against the right command.I refused rather than routing to
update-project. Routing would silently drop the task-only flags —--checklist,--list,--heading— so a caller could get a partial edit reported as a success.Also here: a test that sends a project reference through
editand asserts nothing is opened and the token is right; the new token ininternal/skill/SKILL.mdand the README error list; and a line in the README and site command pages sayingeditis for to-dos only, where someone reads about editing rather than only in the error section.One thing left alone deliberately: the mirror case,
things project edit <to-do>, still returns an unstructurednot a project: …, so under--jsonit lands as the genericerrortoken. Fixing that needs its own token and doc entries, so it belongs in its own change.Closes #189