things-api 0.10.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -13
- package/dist/audit/schema.d.ts +7 -0
- package/dist/audit/schema.js.map +1 -1
- package/dist/cli/clock.d.ts +8 -0
- package/dist/cli/clock.js +24 -0
- package/dist/cli/clock.js.map +1 -0
- package/dist/cli/commands/area.d.ts +18 -11
- package/dist/cli/commands/area.js +61 -74
- package/dist/cli/commands/area.js.map +1 -1
- package/dist/cli/commands/doctor.d.ts +1 -2
- package/dist/cli/commands/doctor.js +11 -1
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/install-skill.d.ts +60 -0
- package/dist/cli/commands/install-skill.js +256 -0
- package/dist/cli/commands/install-skill.js.map +1 -0
- package/dist/cli/commands/mcp.js +9 -0
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/cli/commands/project.d.ts +1 -0
- package/dist/cli/commands/project.js +27 -34
- package/dist/cli/commands/project.js.map +1 -1
- package/dist/cli/commands/reads.d.ts +15 -2
- package/dist/cli/commands/reads.js +144 -44
- package/dist/cli/commands/reads.js.map +1 -1
- package/dist/cli/commands/setup.js +7 -2
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/commands/show.js +38 -14
- package/dist/cli/commands/show.js.map +1 -1
- package/dist/cli/commands/todo.js +15 -9
- package/dist/cli/commands/todo.js.map +1 -1
- package/dist/cli/commands/writes.js +797 -174
- package/dist/cli/commands/writes.js.map +1 -1
- package/dist/cli/did-you-mean.d.ts +14 -3
- package/dist/cli/did-you-mean.js +26 -3
- package/dist/cli/did-you-mean.js.map +1 -1
- package/dist/cli/glyphs.d.ts +32 -2
- package/dist/cli/glyphs.js +83 -12
- package/dist/cli/glyphs.js.map +1 -1
- package/dist/cli/help.js +121 -16
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/main.js +33 -2
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/move-hint.d.ts +46 -0
- package/dist/cli/move-hint.js +196 -0
- package/dist/cli/move-hint.js.map +1 -0
- package/dist/cli/period.d.ts +2 -8
- package/dist/cli/period.js +44 -30
- package/dist/cli/period.js.map +1 -1
- package/dist/cli/read-driver.d.ts +43 -5
- package/dist/cli/read-driver.js +91 -15
- package/dist/cli/read-driver.js.map +1 -1
- package/dist/cli/render.d.ts +19 -8
- package/dist/cli/render.js +70 -27
- package/dist/cli/render.js.map +1 -1
- package/dist/cli/resolve-invocation.d.ts +2 -2
- package/dist/cli/resolve-invocation.js +3 -3
- package/dist/cli/resolve-invocation.js.map +1 -1
- package/dist/cli/skill-check.d.ts +27 -0
- package/dist/cli/skill-check.js +99 -0
- package/dist/cli/skill-check.js.map +1 -0
- package/dist/cli/skill.d.ts +70 -0
- package/dist/cli/skill.js +152 -0
- package/dist/cli/skill.js.map +1 -0
- package/dist/cli/tag-filters.d.ts +6 -2
- package/dist/cli/tag-filters.js +8 -6
- package/dist/cli/tag-filters.js.map +1 -1
- package/dist/cli/verb-hint.js +28 -3
- package/dist/cli/verb-hint.js.map +1 -1
- package/dist/cli/version.d.ts +4 -0
- package/dist/cli/version.js +18 -0
- package/dist/cli/version.js.map +1 -0
- package/dist/client.d.ts +171 -27
- package/dist/client.js +279 -40
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +66 -2
- package/dist/config.js +120 -12
- package/dist/config.js.map +1 -1
- package/dist/contracts.d.ts +186 -28
- package/dist/contracts.js +22 -1
- package/dist/contracts.js.map +1 -1
- package/dist/diagnose.d.ts +34 -2
- package/dist/diagnose.js +36 -1
- package/dist/diagnose.js.map +1 -1
- package/dist/index.d.ts +25 -9
- package/dist/index.js +22 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.d.ts +9 -0
- package/dist/mcp/server.js +1157 -684
- package/dist/mcp/server.js.map +1 -1
- package/dist/model/clock.d.ts +61 -0
- package/dist/model/clock.js +71 -0
- package/dist/model/clock.js.map +1 -0
- package/dist/model/dates.d.ts +26 -3
- package/dist/model/dates.js +84 -3
- package/dist/model/dates.js.map +1 -1
- package/dist/model/entities.d.ts +60 -3
- package/dist/model/entities.js.map +1 -1
- package/dist/model/mappers.d.ts +4 -2
- package/dist/model/mappers.js +66 -9
- package/dist/model/mappers.js.map +1 -1
- package/dist/model/recurrence.d.ts +8 -1
- package/dist/model/recurrence.js.map +1 -1
- package/dist/read/area-filter.d.ts +76 -0
- package/dist/read/area-filter.js +59 -0
- package/dist/read/area-filter.js.map +1 -0
- package/dist/read/area-view.d.ts +12 -12
- package/dist/read/area-view.js +58 -34
- package/dist/read/area-view.js.map +1 -1
- package/dist/read/detail.d.ts +1 -1
- package/dist/read/detail.js +26 -12
- package/dist/read/detail.js.map +1 -1
- package/dist/read/log-boundary.d.ts +1 -1
- package/dist/read/log-boundary.js +13 -3
- package/dist/read/log-boundary.js.map +1 -1
- package/dist/read/predicates.d.ts +18 -0
- package/dist/read/predicates.js +19 -0
- package/dist/read/predicates.js.map +1 -1
- package/dist/read/project-view.d.ts +32 -16
- package/dist/read/project-view.js +80 -45
- package/dist/read/project-view.js.map +1 -1
- package/dist/read/pseudo-area.d.ts +29 -0
- package/dist/read/pseudo-area.js +27 -0
- package/dist/read/pseudo-area.js.map +1 -0
- package/dist/read/queries.d.ts +108 -19
- package/dist/read/queries.js +212 -35
- package/dist/read/queries.js.map +1 -1
- package/dist/read/scope.d.ts +126 -0
- package/dist/read/scope.js +162 -0
- package/dist/read/scope.js.map +1 -0
- package/dist/read/search-rank.d.ts +2 -5
- package/dist/read/shape.d.ts +162 -0
- package/dist/read/shape.js +686 -0
- package/dist/read/shape.js.map +1 -0
- package/dist/read/show-target.d.ts +9 -1
- package/dist/read/show-target.js +45 -4
- package/dist/read/show-target.js.map +1 -1
- package/dist/read/snapshot.d.ts +1 -1
- package/dist/read/snapshot.js +9 -2
- package/dist/read/snapshot.js.map +1 -1
- package/dist/read/stage.d.ts +199 -0
- package/dist/read/stage.js +125 -0
- package/dist/read/stage.js.map +1 -0
- package/dist/read/truncation.d.ts +8 -6
- package/dist/read/truncation.js +35 -10
- package/dist/read/truncation.js.map +1 -1
- package/dist/read/views.d.ts +61 -20
- package/dist/read/views.js +240 -82
- package/dist/read/views.js.map +1 -1
- package/dist/surface-copy.d.ts +9 -0
- package/dist/surface-copy.js +9 -0
- package/dist/surface-copy.js.map +1 -1
- package/dist/write/accessibility-probe.d.ts +1 -1
- package/dist/write/accessibility-probe.js +8 -0
- package/dist/write/accessibility-probe.js.map +1 -1
- package/dist/write/automation-probe.d.ts +1 -1
- package/dist/write/automation-probe.js +8 -0
- package/dist/write/automation-probe.js.map +1 -1
- package/dist/write/batch.d.ts +49 -10
- package/dist/write/batch.js +423 -70
- package/dist/write/batch.js.map +1 -1
- package/dist/write/commands.d.ts +1 -1
- package/dist/write/commands.js +316 -66
- package/dist/write/commands.js.map +1 -1
- package/dist/write/guards.d.ts +1 -1
- package/dist/write/guards.js +94 -10
- package/dist/write/guards.js.map +1 -1
- package/dist/write/heading.d.ts +10 -1
- package/dist/write/heading.js +35 -5
- package/dist/write/heading.js.map +1 -1
- package/dist/write/make-repeating-project.d.ts +2 -2
- package/dist/write/make-repeating-project.js +9 -9
- package/dist/write/make-repeating-project.js.map +1 -1
- package/dist/write/move.d.ts +130 -0
- package/dist/write/move.js +1533 -0
- package/dist/write/move.js.map +1 -0
- package/dist/write/operations.d.ts +105 -19
- package/dist/write/operations.js +56 -7
- package/dist/write/operations.js.map +1 -1
- package/dist/write/opid.d.ts +31 -0
- package/dist/write/opid.js +30 -0
- package/dist/write/opid.js.map +1 -0
- package/dist/write/pipeline.d.ts +122 -3
- package/dist/write/pipeline.js +309 -52
- package/dist/write/pipeline.js.map +1 -1
- package/dist/write/planner.js +8 -1
- package/dist/write/planner.js.map +1 -1
- package/dist/write/pre-state.d.ts +197 -6
- package/dist/write/pre-state.js +427 -20
- package/dist/write/pre-state.js.map +1 -1
- package/dist/write/recurrence-rule-blob.d.ts +65 -0
- package/dist/write/recurrence-rule-blob.js +150 -0
- package/dist/write/recurrence-rule-blob.js.map +1 -0
- package/dist/write/reorder.d.ts +23 -3
- package/dist/write/reorder.js +1871 -85
- package/dist/write/reorder.js.map +1 -1
- package/dist/write/reversibility.js +19 -7
- package/dist/write/reversibility.js.map +1 -1
- package/dist/write/scope-guard.d.ts +31 -0
- package/dist/write/scope-guard.js +162 -0
- package/dist/write/scope-guard.js.map +1 -0
- package/dist/write/undo.js +120 -13
- package/dist/write/undo.js.map +1 -1
- package/dist/write/vectors/applescript.js +16 -7
- package/dist/write/vectors/applescript.js.map +1 -1
- package/dist/write/vectors/registry.d.ts +5 -7
- package/dist/write/vectors/registry.js +49 -2
- package/dist/write/vectors/registry.js.map +1 -1
- package/dist/write/vectors/shortcuts.js +1 -1
- package/dist/write/vectors/shortcuts.js.map +1 -1
- package/dist/write/vectors/simulator.d.ts +44 -0
- package/dist/write/vectors/simulator.js +1192 -0
- package/dist/write/vectors/simulator.js.map +1 -0
- package/dist/write/vectors/types.d.ts +46 -0
- package/dist/write/vectors/ui-certification.d.ts +10 -4
- package/dist/write/vectors/ui-certification.js +43 -10
- package/dist/write/vectors/ui-certification.js.map +1 -1
- package/dist/write/vectors/ui-drag.d.ts +21 -1
- package/dist/write/vectors/ui-drag.js +138 -27
- package/dist/write/vectors/ui-drag.js.map +1 -1
- package/dist/write/vectors/ui-recipes.d.ts +34 -1
- package/dist/write/vectors/ui-recipes.js +217 -6
- package/dist/write/vectors/ui-recipes.js.map +1 -1
- package/dist/write/vectors/ui.d.ts +40 -1
- package/dist/write/vectors/ui.js +196 -39
- package/dist/write/vectors/ui.js.map +1 -1
- package/dist/write/verify/delta.d.ts +127 -2
- package/dist/write/verify/delta.js +255 -16
- package/dist/write/verify/delta.js.map +1 -1
- package/dist/write/verify/poller.d.ts +7 -1
- package/dist/write/verify/poller.js +20 -1
- package/dist/write/verify/poller.js.map +1 -1
- package/package.json +24 -3
- package/schema/envelope.schema.json +383 -0
- package/skills/things-cli/SKILL.md +70 -0
- package/skills/things-cli/references/banner.md +35 -0
- package/skills/things-cli/references/contracts.md +62 -0
- package/skills/things-cli/references/errors.md +49 -0
- package/skills/things-cli/references/gui.md +11 -0
- package/skills/things-cli/references/model.md +60 -0
- package/skills/things-cli/references/ordering.md +71 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# How the user sees Things (the app GUI)
|
|
2
|
+
|
|
3
|
+
Curated rendering facts — the bench loop may compress or relocate these but must never add or change their meaning without Mike's approval (bench/CONSTITUTION.md).
|
|
4
|
+
|
|
5
|
+
<!-- STATUS: v0 seeded from Mike's description 2026-07-17; awaiting his review pass. -->
|
|
6
|
+
|
|
7
|
+
- **Sidebar**: top-level views (Inbox, Today, Upcoming, Anytime, Someday, Logbook, Trash), then each **area** with its active **projects** nested beneath it — in the same order this CLI/API reports them. Reordering areas or projects changes what the user sees there.
|
|
8
|
+
- **List rows are compact**: a to-do in any list shows its checkbox/status, title, tags, deadline, and small marker chips — the Today ★, This Evening ⏾, and (in the Today view only) the provisional `•` "new item" pip, plus has-notes / reminder / checklist glyphs (`things legend` names them all). The **notes TEXT and checklist CONTENTS are invisible until the user opens the item**. Put must-see-at-a-glance information in the title; supporting detail belongs in notes. Projects carry the same Today ★ / This Evening ⏾ pips as to-dos. Why some chips vanish once a row's date goes stale — the reminder bell, the This-Evening section, and the provisional pip — is in [banner.md](banner.md).
|
|
9
|
+
- **Project notes** are likewise visible only when the project itself is opened in project view — in lists, a project is just its title (and progress ring).
|
|
10
|
+
- **Today** shows the day's scheduled items, with **This Evening** as a separate section beneath. **Upcoming** is a forward-looking date-ordered calendar of scheduled items. **Logbook** is where completed/canceled items go — after completing something for the user, that's where they'll find it.
|
|
11
|
+
- When telling the user where something landed, name the container and view ("in project P under area A"; "it'll show in Today this evening").
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# The Things data model (deep reference)
|
|
2
|
+
|
|
3
|
+
Entities, relationships, and how the sidebar views are computed over them, as exposed by the `things` CLI. The SKILL.md "Data model" section is the summary; this is the full version.
|
|
4
|
+
|
|
5
|
+
## Entities
|
|
6
|
+
|
|
7
|
+
| Entity | Container | Can contain | Dates | Tags |
|
|
8
|
+
| --- | --- | --- | --- | --- |
|
|
9
|
+
| To-do | area, project, heading, or NONE (standalone) | checklist items | when, deadline, reminder | own + inherited |
|
|
10
|
+
| Checklist item | its to-do | — | — | — |
|
|
11
|
+
| Heading | its project | to-dos | — | none (inheritance passes through) |
|
|
12
|
+
| Project | area or standalone | headings, to-dos | when, deadline | own + inherited from area |
|
|
13
|
+
| Area | top level | projects, loose to-dos | — | own |
|
|
14
|
+
| Tag | tag hierarchy (may nest) | child tags | — | — |
|
|
15
|
+
|
|
16
|
+
## Rules
|
|
17
|
+
|
|
18
|
+
- A to-do has at most ONE container, and may have none — standalone to-dos (no project, no area) are normal and appear at the top level of Anytime/Someday/Upcoming. Moving changes the container; completing or trashing does not.
|
|
19
|
+
- The **Inbox is a state, not a container**: "in the Inbox" means untriaged — no container AND no schedule. Filing or scheduling an inbox to-do moves it out (filing promotes it to Anytime); moving a to-do TO the Inbox clears both its container and its schedule.
|
|
20
|
+
- A heading is a section label inside one project — not a task. It cannot be scheduled, tagged, or completed; deleting/archiving it affects only the label, per the operation's contract.
|
|
21
|
+
- Tag inheritance flows downward: area → project → (through heading) → to-do. A to-do's *effective* tags = own tags ∪ project tags ∪ area tags. List output distinguishes own vs inherited tags.
|
|
22
|
+
- **Status**: open → completed or canceled (both land in the Logbook) or trashed (Trash; restorable until emptied). Reopen brings a logged item back.
|
|
23
|
+
- **when** (`today | evening | anytime | someday | YYYY-MM-DD`) controls which view an item appears in; **deadline** is an independent due date shown alongside the item; **reminder** is a time-of-day alert attached to a dated when.
|
|
24
|
+
- "Overdue" = open with a deadline strictly before today (a deadline of today is "due", not overdue).
|
|
25
|
+
|
|
26
|
+
## Views (queries over the model)
|
|
27
|
+
|
|
28
|
+
`things inbox|today|upcoming|anytime|someday|logbook|trash` mirror the app's sidebar. Each is a query over the rules above, not a stored list:
|
|
29
|
+
|
|
30
|
+
- **inbox** — untriaged to-dos (no container, no schedule).
|
|
31
|
+
- **today** — items scheduled for today, with the **This Evening** section beneath.
|
|
32
|
+
- **upcoming** — future-dated items, forward-ordered by date.
|
|
33
|
+
- **anytime** — all active items kept without a specific date (standalone or filed).
|
|
34
|
+
- **someday** — items deliberately kept without a date.
|
|
35
|
+
- **logbook** — completed/canceled items.
|
|
36
|
+
- **trash** — trashed items (restorable until the trash is emptied).
|
|
37
|
+
|
|
38
|
+
`things projects`/`areas`/`tags` list containers; `things projects <ref>` / `things areas <ref>` / `things show <ref>` show one item's full detail — notes, checklist, effective tags — which the compact list rows do NOT display.
|
|
39
|
+
|
|
40
|
+
### Reading view membership from JSON — `stage` and `when`
|
|
41
|
+
|
|
42
|
+
Reads decompose an item's position onto two derived, presence-keyed words (they REPLACED the old `start`/`startDate`/`logged`/`trashed`/`todaySection` wire fields, which no longer appear):
|
|
43
|
+
|
|
44
|
+
- **`stage`** — the sidebar BUCKET: `inbox | upcoming | anytime | someday | logbook | trash`. Read view membership off it directly. It is dropped inside a section/catalogue that already states it (the stage-pure `inbox`/`anytime`/`someday`/`logbook`/`trash` lists and the `today` view's sections) and kept everywhere it is not implied (the mixed `upcoming` catalogue, `search`, `changes`, the projects/areas listings, and `detail`).
|
|
45
|
+
- **`when`** — the TIME POSITION: `today | evening | a future ISO date`, or absent (unscheduled and not in Today). `evening` implies today. Someday is a bucket, never a `when`.
|
|
46
|
+
- The two are DIFFERENT facts. A due deadline pulls an UNDATED row into Today: it reads `when: "today"` and derives `stage: "anytime"` — the app re-files a deadline-pulled Inbox/Someday row into Anytime at pull time (R13/BANNER1b), so it drops out of the Inbox/Someday lists and joins Anytime while its `when` reads `today`. Completed/canceled → `stage: "logbook"`, trashed → `stage: "trash"`, regardless of any other hint.
|
|
47
|
+
- `provisional: true` marks a Today member the app has not yet materialized — see [banner.md](banner.md).
|
|
48
|
+
|
|
49
|
+
## Tiers — compact vs full (absence is meaningful)
|
|
50
|
+
|
|
51
|
+
Every row comes back at one of two densities, selected by view kind + flag, never by a caller-supplied field list:
|
|
52
|
+
|
|
53
|
+
- **Compact** (the list default) keeps identity + structural + non-default facts. A field at its default is OMITTED, so absence = the default: no `status` = open, no `checklist` = none, no `todos` = no child to-dos, no `when` = not in Today and unscheduled, no `provisional` = materialized. The full `notes` string is dropped and replaced by presence-keyed `hasNotes: true`; `startDate`, `created`, and `modified` are dropped.
|
|
54
|
+
- **Full** (`show`/`detail`, or a list forced with `--full`) is the whole record — the complete `notes`, the raw `startDate` substrate behind `when`, the checklist `items` array, and timestamps.
|
|
55
|
+
- Compact rows still carry the useful summaries: `checklist:{open,total}` on a to-do, `todos:{open,total}` on a project (app-maintained leaf-action counts — never headings, checklist items, or trashed rows), and `match:{field,text}` on a `search` hit whose match was NOT the title (`field` ∈ `heading | notes | checklist`).
|
|
56
|
+
- **Container absence rule:** inside a single-container node (a project/area card, an `anytime`/`someday` section, a heading group) an item omits any ancestry the node already states, so absent `project`/`area`/`heading` there means *inherited from the enclosing node*. A mixed list (`inbox`/`today`/`search`/`changes`) still names each row's own `project`/`area` (the `heading` ref is compact-dropped outside a project view; `--full` keeps it).
|
|
57
|
+
|
|
58
|
+
## Filters over views
|
|
59
|
+
|
|
60
|
+
Read filters compose with AND: `--tag <name>` (repeatable) / `--untagged` / `--exact-tag` for tags (in single-container `project show` / `area show` these match the row's own tags; in flat views they include inherited tags), `--overdue` (open items whose deadline is before today), `--limit N`, and `--since`/`--until` where offered. `things search <words>` matches title/notes over open items — widen with `--all`, `--logged`, `--trashed`; narrow with `--type project`. `things changes --since <moment>` is the pull-based substitute for a watch mode. Exact flags per command: `things <group> --help` and `things help filters`.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Move and reorder (deep reference)
|
|
2
|
+
|
|
3
|
+
Two verbs, kept strictly apart:
|
|
4
|
+
|
|
5
|
+
- **move** changes WHAT an item belongs to — a to-do's project/area/heading, a project's area.
|
|
6
|
+
- **reorder** changes only the ARRANGEMENT of items already sharing a container and bucket — never membership. Unmentioned siblings keep their order.
|
|
7
|
+
|
|
8
|
+
The SKILL.md summary is enough for most calls; this page is the full contract. Exact flags always come from `things todo move --help`, `things project move --help`, and `things reorder --help` (current for the binary you invoke).
|
|
9
|
+
|
|
10
|
+
## Move — changing membership
|
|
11
|
+
|
|
12
|
+
**To-dos** (`things todo move <refs…> [destination] [position]`, one destination):
|
|
13
|
+
|
|
14
|
+
- `--to-project <ref>` · `--to-heading <sel>` · `--to-area <ref>` — place into a container.
|
|
15
|
+
- Detach family: `--no-heading` (leave the heading, stay in the project) · `--loose` (leave heading, project, AND area) · `--inbox` (back to the Inbox — this also DROPS the schedule).
|
|
16
|
+
- There is no `--detach` (removed) and no `--no-area` on a to-do — a to-do's area is inherited, so use `--loose`.
|
|
17
|
+
|
|
18
|
+
**Projects** (`things project move <refs…> [--to-area <ref> | --no-area] [position]`): `--no-area` is a project's detach (the to-do word `--loose` is refused on a project).
|
|
19
|
+
|
|
20
|
+
**`--to-heading` scoping.** A heading selector (exact title or uuid) resolves within the movees' shared project; when the movees are not already all in that project, name it with `--to-project`. A heading belongs to one project and cannot hold projects.
|
|
21
|
+
|
|
22
|
+
## Reorder — changing arrangement
|
|
23
|
+
|
|
24
|
+
`things reorder <refs…> [--first | --last | --before <ref> | --after <ref>] [--in <target>]` is the ONE kind-neutral in-place verb (it replaced the old `todo reorder` subcommand and the raw `reorder --scope`). It rearranges to-dos AND the project rows the Today/Evening/day lists intermix with them.
|
|
25
|
+
|
|
26
|
+
- **Bare (no position)**: the named items assemble as ONE block at the EARLIEST one's current slot, in argument order (`--first` is NOT implied). Partial selection is fine — unmentioned siblings keep their order.
|
|
27
|
+
- **Positioned**: `--first`/`--last` send the block to the top/bottom of its bucket; `--before <ref>`/`--after <ref>` place it relative to an anchor.
|
|
28
|
+
- **Selection order = landing order** (reverse by naming the refs backwards).
|
|
29
|
+
- **Mixed to-do + project refs are allowed** in the Today/Evening/day buckets those kinds share; elsewhere reorder operates within one container+bucket.
|
|
30
|
+
|
|
31
|
+
Sibling verbs for the two things `reorder` does NOT touch: `things project move-heading` reorders a project's HEADINGS; `things area reorder` reorders the sidebar AREAS.
|
|
32
|
+
|
|
33
|
+
## Anchors POSITION, never MIGRATE
|
|
34
|
+
|
|
35
|
+
A `--before`/`--after` anchor only says WHERE in a bucket — it never moves the anchor and never reschedules a movee to reach it. The anchor must already sit in the movees' container+bucket; a cross-container or cross-bucket anchor **fails closed** with a message naming where the rows and the anchor actually are (no silent rescheduling). For a global-axis bucket (today/evening/tomorrow/a future day-group) the anchor need only share the movees' day-group, not their structural container — the app permits exactly that drag.
|
|
36
|
+
|
|
37
|
+
## The dual axis and `--in` (fail-closed)
|
|
38
|
+
|
|
39
|
+
A Today/Evening member has TWO order slots: its slot in the Today VIEW (`todayIndex`) and its slot in its own CONTAINER (`index` — a project/area/heading child, or the loose Anytime bucket). When a set (and its anchor) is coherent on BOTH axes and no `--in` is given, the reorder is REFUSED with a message naming both readings and their exact `--in` spellings — this replaces any silent always-Today guess.
|
|
40
|
+
|
|
41
|
+
- `--in` accepts `today | evening | anytime | someday | inbox`, or a project/area/heading ref (uuid or unique title). `loose` is refused (it is a read view, not a bucket).
|
|
42
|
+
- Forcing the container index axis on a Today/Evening member PRESERVES the Today/Evening flag — a flag-safe move protocol routes it off the de-Today path. Only the someday/inbox loose axes still refuse a flagged member (their re-entry cannot preserve the flag).
|
|
43
|
+
|
|
44
|
+
## Mixed-stage move placement
|
|
45
|
+
|
|
46
|
+
A `move` selection spanning stage sub-buckets (anytime + scheduled + someday + templates):
|
|
47
|
+
|
|
48
|
+
- `--before`/`--after` is REFUSED unless every movee shares the anchor's sub-bucket (remediation: split the call, or drop the anchor).
|
|
49
|
+
- `--first`/`--last` apply PER sub-bucket — each stage-group lands at the top/bottom of ITS matching bucket in the destination, and the result note states every group's placement outcome.
|
|
50
|
+
|
|
51
|
+
## Gates, caps, and automatic fallbacks
|
|
52
|
+
|
|
53
|
+
Three config knobs (`things config get/set …`) tune ordering; every default gives full sortability:
|
|
54
|
+
|
|
55
|
+
- **`allow-experimental`** (default `true`) — enables the private NATIVE re-rank command for the scopes only it can reach directly (`inbox`, `someday`, a project's unheaded children, an area's members, a container's same-day children, `tomorrow`). It is the off-switch, not an opt-in.
|
|
56
|
+
- **`bounce-enabled`** (default `true`) — permits the verified `when=`/move round-trip protocols the other scopes use. `false` REFUSES a bounce-dependent placement rather than degrading destructively.
|
|
57
|
+
- **`bounce-max-items`** (default `30`) — caps how many items one bounce may touch; a set larger than the cap is refused, not truncated.
|
|
58
|
+
|
|
59
|
+
**Automatic non-experimental fallbacks (SIT7).** When `allow-experimental` is off (or the native surface is unavailable), the native-only scopes DO NOT fail — each degrades to a proven, verified, flag-safe move protocol (park-and-re-home for `inbox`/`project`/`area`, a `when=` bounce for `someday` and day-groups). Collateral is preserved (Today/Evening flag, live reminder, deadline, container FKs). The result's `warnings` note discloses which fallback ran (e.g. "reordered via the non-experimental PROJROOT fallback because the native reorder is unavailable") — a native placement is never silently mistaken for a degraded one.
|
|
60
|
+
|
|
61
|
+
**Flag-aware routing (SIT6).** A reorder touching a Today/Evening-FLAGGED row never de-Todays it: the whole touched set swaps to a flag-safe MOVE protocol on the same axis (the `when=` bounce would strip the flag). This is transparent — you still call `things reorder`; the chosen strategy is disclosed in the result.
|
|
62
|
+
|
|
63
|
+
## Placement guarantees and the one dead class
|
|
64
|
+
|
|
65
|
+
"Top of bucket in selection order" is GUARANTEED wherever a lab-clean protocol exists: loose inbox/today/evening/someday/anytime; a project's or area's members (anytime AND someday); a heading's anytime/someday children; any container child's evening slot; area-less someday/anytime projects; and a whole future day-group across containers (including scheduled project rows, area'd ones too). The result's placement class names which guarantee you got, and a bounce that co-touches unnamed siblings to honor a `--before`/`--after` anchor lists them.
|
|
66
|
+
|
|
67
|
+
**The one class that cannot be reordered is a repeating TEMPLATE** — a dated `when=` leg crashes it, so a template movee or anchor is refused and template placement stays app-default (disclosed). Everything non-template is sortable.
|
|
68
|
+
|
|
69
|
+
## MCP parity
|
|
70
|
+
|
|
71
|
+
The MCP server exposes reorder as two tools: **`reorder`** (the planner form — `refs`, an optional position, an optional `in` axis) mirrors `things reorder`, and **`reorder_areas`** mirrors `things area reorder` (sidebar areas, with the same two-key GUI gate). Both call the same library entries the CLI does, so the dual-axis refusal, the flag-safe routing, and the automatic fallbacks behave identically.
|