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.
Files changed (239) hide show
  1. package/README.md +50 -13
  2. package/dist/audit/schema.d.ts +7 -0
  3. package/dist/audit/schema.js.map +1 -1
  4. package/dist/cli/clock.d.ts +8 -0
  5. package/dist/cli/clock.js +24 -0
  6. package/dist/cli/clock.js.map +1 -0
  7. package/dist/cli/commands/area.d.ts +18 -11
  8. package/dist/cli/commands/area.js +61 -74
  9. package/dist/cli/commands/area.js.map +1 -1
  10. package/dist/cli/commands/doctor.d.ts +1 -2
  11. package/dist/cli/commands/doctor.js +11 -1
  12. package/dist/cli/commands/doctor.js.map +1 -1
  13. package/dist/cli/commands/install-skill.d.ts +60 -0
  14. package/dist/cli/commands/install-skill.js +256 -0
  15. package/dist/cli/commands/install-skill.js.map +1 -0
  16. package/dist/cli/commands/mcp.js +9 -0
  17. package/dist/cli/commands/mcp.js.map +1 -1
  18. package/dist/cli/commands/project.d.ts +1 -0
  19. package/dist/cli/commands/project.js +27 -34
  20. package/dist/cli/commands/project.js.map +1 -1
  21. package/dist/cli/commands/reads.d.ts +15 -2
  22. package/dist/cli/commands/reads.js +144 -44
  23. package/dist/cli/commands/reads.js.map +1 -1
  24. package/dist/cli/commands/setup.js +7 -2
  25. package/dist/cli/commands/setup.js.map +1 -1
  26. package/dist/cli/commands/show.js +38 -14
  27. package/dist/cli/commands/show.js.map +1 -1
  28. package/dist/cli/commands/todo.js +15 -9
  29. package/dist/cli/commands/todo.js.map +1 -1
  30. package/dist/cli/commands/writes.js +797 -174
  31. package/dist/cli/commands/writes.js.map +1 -1
  32. package/dist/cli/did-you-mean.d.ts +14 -3
  33. package/dist/cli/did-you-mean.js +26 -3
  34. package/dist/cli/did-you-mean.js.map +1 -1
  35. package/dist/cli/glyphs.d.ts +32 -2
  36. package/dist/cli/glyphs.js +83 -12
  37. package/dist/cli/glyphs.js.map +1 -1
  38. package/dist/cli/help.js +121 -16
  39. package/dist/cli/help.js.map +1 -1
  40. package/dist/cli/main.js +33 -2
  41. package/dist/cli/main.js.map +1 -1
  42. package/dist/cli/move-hint.d.ts +46 -0
  43. package/dist/cli/move-hint.js +196 -0
  44. package/dist/cli/move-hint.js.map +1 -0
  45. package/dist/cli/period.d.ts +2 -8
  46. package/dist/cli/period.js +44 -30
  47. package/dist/cli/period.js.map +1 -1
  48. package/dist/cli/read-driver.d.ts +43 -5
  49. package/dist/cli/read-driver.js +91 -15
  50. package/dist/cli/read-driver.js.map +1 -1
  51. package/dist/cli/render.d.ts +19 -8
  52. package/dist/cli/render.js +70 -27
  53. package/dist/cli/render.js.map +1 -1
  54. package/dist/cli/resolve-invocation.d.ts +2 -2
  55. package/dist/cli/resolve-invocation.js +3 -3
  56. package/dist/cli/resolve-invocation.js.map +1 -1
  57. package/dist/cli/skill-check.d.ts +27 -0
  58. package/dist/cli/skill-check.js +99 -0
  59. package/dist/cli/skill-check.js.map +1 -0
  60. package/dist/cli/skill.d.ts +70 -0
  61. package/dist/cli/skill.js +152 -0
  62. package/dist/cli/skill.js.map +1 -0
  63. package/dist/cli/tag-filters.d.ts +6 -2
  64. package/dist/cli/tag-filters.js +8 -6
  65. package/dist/cli/tag-filters.js.map +1 -1
  66. package/dist/cli/verb-hint.js +28 -3
  67. package/dist/cli/verb-hint.js.map +1 -1
  68. package/dist/cli/version.d.ts +4 -0
  69. package/dist/cli/version.js +18 -0
  70. package/dist/cli/version.js.map +1 -0
  71. package/dist/client.d.ts +171 -27
  72. package/dist/client.js +279 -40
  73. package/dist/client.js.map +1 -1
  74. package/dist/config.d.ts +66 -2
  75. package/dist/config.js +120 -12
  76. package/dist/config.js.map +1 -1
  77. package/dist/contracts.d.ts +186 -28
  78. package/dist/contracts.js +22 -1
  79. package/dist/contracts.js.map +1 -1
  80. package/dist/diagnose.d.ts +34 -2
  81. package/dist/diagnose.js +36 -1
  82. package/dist/diagnose.js.map +1 -1
  83. package/dist/index.d.ts +25 -9
  84. package/dist/index.js +22 -3
  85. package/dist/index.js.map +1 -1
  86. package/dist/mcp/server.d.ts +9 -0
  87. package/dist/mcp/server.js +1157 -684
  88. package/dist/mcp/server.js.map +1 -1
  89. package/dist/model/clock.d.ts +61 -0
  90. package/dist/model/clock.js +71 -0
  91. package/dist/model/clock.js.map +1 -0
  92. package/dist/model/dates.d.ts +26 -3
  93. package/dist/model/dates.js +84 -3
  94. package/dist/model/dates.js.map +1 -1
  95. package/dist/model/entities.d.ts +60 -3
  96. package/dist/model/entities.js.map +1 -1
  97. package/dist/model/mappers.d.ts +4 -2
  98. package/dist/model/mappers.js +66 -9
  99. package/dist/model/mappers.js.map +1 -1
  100. package/dist/model/recurrence.d.ts +8 -1
  101. package/dist/model/recurrence.js.map +1 -1
  102. package/dist/read/area-filter.d.ts +76 -0
  103. package/dist/read/area-filter.js +59 -0
  104. package/dist/read/area-filter.js.map +1 -0
  105. package/dist/read/area-view.d.ts +12 -12
  106. package/dist/read/area-view.js +58 -34
  107. package/dist/read/area-view.js.map +1 -1
  108. package/dist/read/detail.d.ts +1 -1
  109. package/dist/read/detail.js +26 -12
  110. package/dist/read/detail.js.map +1 -1
  111. package/dist/read/log-boundary.d.ts +1 -1
  112. package/dist/read/log-boundary.js +13 -3
  113. package/dist/read/log-boundary.js.map +1 -1
  114. package/dist/read/predicates.d.ts +18 -0
  115. package/dist/read/predicates.js +19 -0
  116. package/dist/read/predicates.js.map +1 -1
  117. package/dist/read/project-view.d.ts +32 -16
  118. package/dist/read/project-view.js +80 -45
  119. package/dist/read/project-view.js.map +1 -1
  120. package/dist/read/pseudo-area.d.ts +29 -0
  121. package/dist/read/pseudo-area.js +27 -0
  122. package/dist/read/pseudo-area.js.map +1 -0
  123. package/dist/read/queries.d.ts +108 -19
  124. package/dist/read/queries.js +212 -35
  125. package/dist/read/queries.js.map +1 -1
  126. package/dist/read/scope.d.ts +126 -0
  127. package/dist/read/scope.js +162 -0
  128. package/dist/read/scope.js.map +1 -0
  129. package/dist/read/search-rank.d.ts +2 -5
  130. package/dist/read/shape.d.ts +162 -0
  131. package/dist/read/shape.js +686 -0
  132. package/dist/read/shape.js.map +1 -0
  133. package/dist/read/show-target.d.ts +9 -1
  134. package/dist/read/show-target.js +45 -4
  135. package/dist/read/show-target.js.map +1 -1
  136. package/dist/read/snapshot.d.ts +1 -1
  137. package/dist/read/snapshot.js +9 -2
  138. package/dist/read/snapshot.js.map +1 -1
  139. package/dist/read/stage.d.ts +199 -0
  140. package/dist/read/stage.js +125 -0
  141. package/dist/read/stage.js.map +1 -0
  142. package/dist/read/truncation.d.ts +8 -6
  143. package/dist/read/truncation.js +35 -10
  144. package/dist/read/truncation.js.map +1 -1
  145. package/dist/read/views.d.ts +61 -20
  146. package/dist/read/views.js +240 -82
  147. package/dist/read/views.js.map +1 -1
  148. package/dist/surface-copy.d.ts +9 -0
  149. package/dist/surface-copy.js +9 -0
  150. package/dist/surface-copy.js.map +1 -1
  151. package/dist/write/accessibility-probe.d.ts +1 -1
  152. package/dist/write/accessibility-probe.js +8 -0
  153. package/dist/write/accessibility-probe.js.map +1 -1
  154. package/dist/write/automation-probe.d.ts +1 -1
  155. package/dist/write/automation-probe.js +8 -0
  156. package/dist/write/automation-probe.js.map +1 -1
  157. package/dist/write/batch.d.ts +49 -10
  158. package/dist/write/batch.js +423 -70
  159. package/dist/write/batch.js.map +1 -1
  160. package/dist/write/commands.d.ts +1 -1
  161. package/dist/write/commands.js +316 -66
  162. package/dist/write/commands.js.map +1 -1
  163. package/dist/write/guards.d.ts +1 -1
  164. package/dist/write/guards.js +94 -10
  165. package/dist/write/guards.js.map +1 -1
  166. package/dist/write/heading.d.ts +10 -1
  167. package/dist/write/heading.js +35 -5
  168. package/dist/write/heading.js.map +1 -1
  169. package/dist/write/make-repeating-project.d.ts +2 -2
  170. package/dist/write/make-repeating-project.js +9 -9
  171. package/dist/write/make-repeating-project.js.map +1 -1
  172. package/dist/write/move.d.ts +130 -0
  173. package/dist/write/move.js +1533 -0
  174. package/dist/write/move.js.map +1 -0
  175. package/dist/write/operations.d.ts +105 -19
  176. package/dist/write/operations.js +56 -7
  177. package/dist/write/operations.js.map +1 -1
  178. package/dist/write/opid.d.ts +31 -0
  179. package/dist/write/opid.js +30 -0
  180. package/dist/write/opid.js.map +1 -0
  181. package/dist/write/pipeline.d.ts +122 -3
  182. package/dist/write/pipeline.js +309 -52
  183. package/dist/write/pipeline.js.map +1 -1
  184. package/dist/write/planner.js +8 -1
  185. package/dist/write/planner.js.map +1 -1
  186. package/dist/write/pre-state.d.ts +197 -6
  187. package/dist/write/pre-state.js +427 -20
  188. package/dist/write/pre-state.js.map +1 -1
  189. package/dist/write/recurrence-rule-blob.d.ts +65 -0
  190. package/dist/write/recurrence-rule-blob.js +150 -0
  191. package/dist/write/recurrence-rule-blob.js.map +1 -0
  192. package/dist/write/reorder.d.ts +23 -3
  193. package/dist/write/reorder.js +1871 -85
  194. package/dist/write/reorder.js.map +1 -1
  195. package/dist/write/reversibility.js +19 -7
  196. package/dist/write/reversibility.js.map +1 -1
  197. package/dist/write/scope-guard.d.ts +31 -0
  198. package/dist/write/scope-guard.js +162 -0
  199. package/dist/write/scope-guard.js.map +1 -0
  200. package/dist/write/undo.js +120 -13
  201. package/dist/write/undo.js.map +1 -1
  202. package/dist/write/vectors/applescript.js +16 -7
  203. package/dist/write/vectors/applescript.js.map +1 -1
  204. package/dist/write/vectors/registry.d.ts +5 -7
  205. package/dist/write/vectors/registry.js +49 -2
  206. package/dist/write/vectors/registry.js.map +1 -1
  207. package/dist/write/vectors/shortcuts.js +1 -1
  208. package/dist/write/vectors/shortcuts.js.map +1 -1
  209. package/dist/write/vectors/simulator.d.ts +44 -0
  210. package/dist/write/vectors/simulator.js +1192 -0
  211. package/dist/write/vectors/simulator.js.map +1 -0
  212. package/dist/write/vectors/types.d.ts +46 -0
  213. package/dist/write/vectors/ui-certification.d.ts +10 -4
  214. package/dist/write/vectors/ui-certification.js +43 -10
  215. package/dist/write/vectors/ui-certification.js.map +1 -1
  216. package/dist/write/vectors/ui-drag.d.ts +21 -1
  217. package/dist/write/vectors/ui-drag.js +138 -27
  218. package/dist/write/vectors/ui-drag.js.map +1 -1
  219. package/dist/write/vectors/ui-recipes.d.ts +34 -1
  220. package/dist/write/vectors/ui-recipes.js +217 -6
  221. package/dist/write/vectors/ui-recipes.js.map +1 -1
  222. package/dist/write/vectors/ui.d.ts +40 -1
  223. package/dist/write/vectors/ui.js +196 -39
  224. package/dist/write/vectors/ui.js.map +1 -1
  225. package/dist/write/verify/delta.d.ts +127 -2
  226. package/dist/write/verify/delta.js +255 -16
  227. package/dist/write/verify/delta.js.map +1 -1
  228. package/dist/write/verify/poller.d.ts +7 -1
  229. package/dist/write/verify/poller.js +20 -1
  230. package/dist/write/verify/poller.js.map +1 -1
  231. package/package.json +24 -3
  232. package/schema/envelope.schema.json +383 -0
  233. package/skills/things-cli/SKILL.md +70 -0
  234. package/skills/things-cli/references/banner.md +35 -0
  235. package/skills/things-cli/references/contracts.md +62 -0
  236. package/skills/things-cli/references/errors.md +49 -0
  237. package/skills/things-cli/references/gui.md +11 -0
  238. package/skills/things-cli/references/model.md +60 -0
  239. package/skills/things-cli/references/ordering.md +71 -0
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  A typed TypeScript library + CLI (`things`) for programmatic interaction with [Things 3](https://culturedcode.com/things/) by Cultured Code.
4
4
 
5
- **Status: read + write + MCP layers live and published to npm (v0.10.0 — see [CHANGELOG.md](CHANGELOG.md)).** Reads go straight to the local SQLite database (UI-exact Today ordering, sidebar-grouped Anytime/Someday with container-status cascade, decoded repeat rules, occurrence projections); writes run a verified pipeline over four write vectors — two lab-validated headless surfaces (the URL scheme + AppleScript) and two opt-in surfaces (Apple Shortcuts and an Accessibility-driven GUI vector) — with hazard guards, disruption-tier policy, a JSONL audit trail, batch mode, audit-replay undo (transactional across compound operations), full project lifecycle (complete/cancel/reopen/restore), heading rename/archive/unarchive with children policies, container detach, granular stateful checklists, tag hierarchy management incl. un-nesting, completion/creation backdating, Logbook imports, tiered fuzzy name resolution (uuid prefixes, `things:///show?id=` share links), and ordering across eight scopes (incl. a project's headings and the top-level sidebar projects). The Apple Shortcuts surface is wired for the two headless capabilities nothing else can do: creating a heading in an existing project (`things heading add`) and clearing a reminder from a date-scheduled item (`things todo clear-reminder`). Both run through bundled proxy shortcuts (`things setup shortcuts`) and are gated on their presence. The fourth vector — the Accessibility-driven GUI vector — is off by default and drives the local Things app to reach transforms that exist on no scriptable surface (repeat-rule editing on existing to-dos and projects, convert-to-project, sidebar area reorder); see [Accessibility GUI vector](#accessibility-gui-vector-optional-off-by-default) below. Single-item permanent delete stays interactive-only (its macOS consent has no always-allow) and is out of the headless pipeline. See [docs/design/](docs/design/) for the architecture and VM-lab design, [docs/lab/](docs/lab/harness.md) for the probe harness and campaign results the write layer is grounded in, and [docs/atlas/](docs/atlas/schema-v26.md) for the database↔UI map.
5
+ **Status: read + write + MCP layers live and published to npm (v0.12.0 — see [CHANGELOG.md](CHANGELOG.md)).** Reads go straight to the local SQLite database (UI-exact Today ordering, sidebar-grouped Anytime/Someday with container-status cascade, decoded repeat rules, occurrence projections); writes run a verified pipeline over four write vectors — two lab-validated headless surfaces (the URL scheme + AppleScript) and two opt-in surfaces (Apple Shortcuts and an Accessibility-driven GUI vector) — with hazard guards, disruption-tier policy, a JSONL audit trail, batch mode, audit-replay undo (transactional across compound operations), full project lifecycle (complete/cancel/reopen/restore), heading rename/archive/unarchive with children policies, container detach, granular stateful checklists, tag hierarchy management incl. un-nesting, completion/creation backdating, Logbook imports, tiered fuzzy name resolution (uuid prefixes, `things:///show?id=` share links), and ordering across eight scopes (incl. a project's headings and the top-level sidebar projects). The Apple Shortcuts surface is wired for the two headless capabilities nothing else can do: creating a heading in an existing project (`things heading add`) and clearing a reminder from a date-scheduled item (`things todo clear-reminder`). Both run through bundled proxy shortcuts (`things setup shortcuts`) and are gated on their presence. The fourth vector — the Accessibility-driven GUI vector — is off by default and drives the local Things app to reach transforms that exist on no scriptable surface (repeat-rule editing on existing to-dos and projects, convert-to-project, sidebar area reorder); see [Accessibility GUI vector](#accessibility-gui-vector-optional-off-by-default) below. Single-item permanent delete stays interactive-only (its macOS consent has no always-allow) and is out of the headless pipeline. See [docs/design/](docs/design/) for the architecture and VM-lab design, [docs/lab/](docs/lab/harness.md) for the probe harness and campaign results the write layer is grounded in, and [docs/atlas/](docs/atlas/schema-v26.md) for the database↔UI map.
6
6
 
7
7
  ```sh
8
8
  things today --json # read: your Today list, Evening split, UI order
@@ -13,6 +13,15 @@ things undo --dry-run # inverse plan for the last mutation (audit r
13
13
  things capabilities --op todo.delete # what's possible, per vector, with evidence
14
14
  ```
15
15
 
16
+ ## Why this wrapper is different
17
+
18
+ Most ways to script Things fire a URL or an AppleScript command and hope. This package is built on four commitments instead, and each is a checkable property of the response, not a claim in the docs:
19
+
20
+ - **Verified writes — `ok` means observed, not submitted.** Every mutation runs a read-after-write pipeline: it re-reads the database and confirms the expected change is actually present before returning `ok: true`. The app accepting a command and silently doing nothing (a real Things behavior) is reported as a failure (`verify-failed:silent-noop`), never as success. A caller can act on `ok: true` without a confirming read of its own.
21
+ - **Safety rails.** Writes go exclusively through official app surfaces — URL scheme, AppleScript, Shortcuts, and the opt-in Accessibility GUI vector — never direct SQLite writes (which corrupt Things Cloud sync). Every operation carries a disruption tier (0 invisible → 3 drives the live UI) and passes hazard guards before dispatch; disruptive and destructive actions require explicit acknowledgement flags, never an interactive prompt. A process can be jailed to one container with `--scope` (an area or project), and an out-of-scope item is byte-indistinguishable from a nonexistent one.
22
+ - **A written contract, not a vibe.** Every `--json` response is one instance of a small, stable envelope grammar (`apiVersion`, `ok`, `kind`, `data`, `meta`), with a frozen exit-code family, a one-word-one-meaning glossary, and a machine-readable error-code registry. The full contract — including the compatibility covenant that activates at v1.0 — is in **[docs/contract.md](docs/contract.md)**; the design rationale is in [docs/design/api-doctrine.md](docs/design/api-doctrine.md).
23
+ - **Agent-native by design.** Errors are self-correcting: an ambiguous name comes back with uuid-bearing candidates, a bare verb with the exact command to run instead, so an agent fixes its own mistake without another round-trip. Reads never cap silently — `meta.truncation.truncated` is the universal "did I see everything" check. And the wire is kept dense on purpose (empty fields pruned, no redundant discriminators), because when the consumer pays per token, information density is a correctness concern. Consumer-facing copy follows a strict behavior-not-mechanism contract ([docs/design/surface-copy.md](docs/design/surface-copy.md)).
24
+
16
25
  ## Requirements & first-run setup
17
26
 
18
27
  Things 3 installed and launched once, Node ≥ 24, and a handful of one-time macOS consents / Things settings depending on what you use (file-access consent for reads; "Enable Things URLs" + Automation consents for writes; an Accessibility grant for the optional GUI vector). **See [docs/setup.md](docs/setup.md)** — including the dedicated-automation-Mac checklist. `things doctor` validates your setup and prints remediation for anything missing.
@@ -27,7 +36,7 @@ things setup shortcuts # opens an install sheet per missing shortcut — click
27
36
 
28
37
  On each shortcut's first run macOS asks for permission — choose **Always Allow** so later runs are unattended (the two delete shortcuts re-ask on every run by design; Apple offers no always-allow for deletion). `things setup shortcuts --check` and `things doctor` report installation state.
29
38
 
30
- Once installed, these Shortcuts-only operations become available as ordinary commands: `things heading add <project> <title>` (create a heading in an existing project) and `things todo clear-reminder <uuid>` (clear a date-scheduled to-do's reminder while keeping its date). Both are also exposed over MCP (`create_heading`, `clear_reminder`). If a required shortcut is missing, the command is blocked up front with a pointer back to `things setup shortcuts` — nothing is dispatched.
39
+ Once installed, these Shortcuts-only operations become available as ordinary commands: `things heading add <project> <title>` (create a heading in an existing project) and `things todo clear-reminder <uuid>` (clear a date-scheduled to-do's reminder while keeping its date). Both are also exposed over MCP (the `heading` tool's create action, and `clear_reminder`). If a required shortcut is missing, the command is blocked up front with a pointer back to `things setup shortcuts` — nothing is dispatched.
31
40
 
32
41
  ### Accessibility GUI vector (optional, off by default)
33
42
 
@@ -48,6 +57,8 @@ asdf reshim nodejs # once, if you use asdf: expose the new `things` shim
48
57
 
49
58
  Edits under `src/` take effect immediately. The bin launcher ([bin/things.js](bin/things.js)) prefers `src/` when present and falls back to `dist/`, so published installs (`npm i -g things-api`, `npx things-api`) run the compiled output with identical behavior.
50
59
 
60
+ `npm run explore` starts a localhost-only debug view (default `127.0.0.1:5711`, `--port <n>` to change, `--no-open` to skip the browser): pick a preset or type any `things …` command and read the emitted envelope as a collapsible JSON tree, live against your default database. Reads run verbatim; every other command gets `--dry-run` force-appended server-side (the response echoes the exact argv that ran, forced flags included), so mutations can only ever produce plans. `THINGS_DB` / `THINGS_NOW` / `THINGS_TZ` set before launching apply to every command the view runs. Add `--public` to bind `0.0.0.0` for token-gated LAN access (phones/tablets on the same network): startup prints each LAN URL with a random per-launch `?key=` that plants a signed-in cookie on first open.
61
+
51
62
  ## Core principles
52
63
 
53
64
  - **Reads** go directly to Things' local SQLite database (read-only, WAL-aware). **Writes** go exclusively through official app surfaces — URL scheme, AppleScript, Shortcuts, and (opt-in) the Accessibility-driven GUI — never direct DB writes (sync corruption).
@@ -62,11 +73,12 @@ Edits under `src/` take effect immediately. The bin launcher ([bin/things.js](bi
62
73
  The CLI is designed to be driven by coding agents with no out-of-band knowledge. The contract:
63
74
 
64
75
  1. **Discovery**: `things --help` (a grouped one-line-per-command index; orientation detail lives behind `things help <topic>` — `agent`, `filters`, `ids`, `output`, `writes`), per-command `things <command> --help` (behavior, side effects, and the exact acknowledgement flag names a write needs — regression-tested as API; by design it does **not** carry vector/tier/hazard vocabulary, which is banned from help text by [docs/design/surface-copy.md](docs/design/surface-copy.md) — that classification lives in `capabilities`), and `things capabilities [--op <op>] --json` (the lab-validated operation × vector support matrix with disruption tiers, hazards, per-op certification status, and probe-evidence ids). Command invocation follows one grammar (`things <view>` · `things <type> <verb> <subject>` · loose `things <verb> <subject>` · bare `things <subject>`) with a single precedence chain — registered command/alias → view keyword → reference resolution — specified in [docs/design/cli-grammar.md](docs/design/cli-grammar.md).
65
- 2. **Structured output**: every command takes `--json` → versioned envelope `{ apiVersion, ok, kind, data|error, meta }` on stdout; human chatter goes to stderr only. List views are **bounded by default**: the flat/chronological views (`inbox`, `today`, `upcoming`, `logbook`, `trash`, `search`, `changes`) return at most 50 items — raise with `--limit <n>` or lift with `--all` — and carry exact truncation counts in `meta.truncation { shown, total, limit, truncated }` (the split `today` view also breaks the counts down per render section under `sections`). The grouped catalogues (`anytime`, `someday`) always show every area and project row and cap per block instead (no `--limit`): `--area-limit <n>` (default 30) per area block on both, `--project-limit <n>` (default 3) per project block on anytime, `--show-active-project-items [n]` for someday's trailing active-projects section — reporting `meta.grouped { truncated, blocks[] }`, where each block is identity-carrying (`kind`, `ref`, `title`, `shown`, `total`) and project blocks nest inside their area block under `children`. A read whose database schema no longer matches this build's validated fingerprint carries a non-blocking `meta.warnings` note (the read still returns best-effort; the same drift hard-blocks writes). Same defaults and metadata apply over MCP.
76
+ 2. **Structured output**: every command takes `--json` → versioned envelope `{ apiVersion, ok, kind, data|error, meta }` on stdout; human chatter goes to stderr only. List views are **bounded by default**: the flat/chronological views (`inbox`, `today`, `upcoming`, `logbook`, `trash`, `search`, `changes`) return at most 50 items — raise with `--limit <n>` or lift with `--all` — and carry exact truncation counts in `meta.truncation { shown, total, limit, truncated }` (the split `today` view also breaks the counts down per render section under `sections`). The grouped catalogues (`anytime`, `someday`) always show every area and project row and cap per block instead (no `--limit`): `--area-limit <n>` (default 30) per area block on both, `--project-limit <n>` (default 3) per project block on anytime, `--show-active-project-items [n]` for someday's trailing active-projects section — reporting the same `meta.truncation` shape with a per-block `blocks[]` breakdown (aggregate `shown`/`total`, `limit: null`), where each block is identity-carrying (`kind`, `ref`, `title`, `shown`, `total`) and project blocks nest inside their area block under `children`. A read whose database schema no longer matches this build's validated fingerprint carries a non-blocking `meta.warnings` note (the read still returns best-effort; the same drift hard-blocks writes). Same defaults and metadata apply over MCP.
66
77
  3. **Stable exit codes**: `0` ok · `2` usage · `3` verify-failed (mutation executed, expected delta never appeared) · `4` blocked (hazard guard or disruption policy; error carries `remediation`) · `5` drift-blocked · `6` unsupported (op has no supported vector — `things batch` also aggregates to 6 when its only failures are unsupported ops) · `7` environment.
67
78
  4. **Plan before executing**: every write supports `--dry-run` — compiled invocation (token-redacted), chosen vector, tier, hazards checked, expected delta. Nothing runs, nothing is audited.
68
79
  5. **No prompts, ever**: risky semantics are explicit flags — `--children require-resolved|auto-complete` (project completion cascades), `--acknowledge-checklist-reset` (checklist replacement destroys per-item state), `--acknowledge-project-reopen` (open child reopens a resolved project), `--dangerously-permanent` (area/tag delete and empty-trash skip the Trash), `--dangerously-drive-gui` (each Accessibility GUI-vector call).
69
- 6. **Experimental surfaces are opt-in**: `things reorder` (ordering within Today, the Inbox, Someday, a project's to-dos, a project's headings, or an area) rides an undocumented AppleScript command that any Things update may remove. It requires `things config set allow-experimental true` and re-checks the app's sdef declaration before every dispatch; `things doctor` reports both gates. Two scopes never touch it: This Evening and the top-level sidebar projects use verified `when=` round-trips (the "bounce", ≤10 items) instead. Reordering the areas themselves (the sidebar order) is a separate operation on the Accessibility GUI vector (`things area reorder`, MCP `reorder_area`).
80
+ 6. **Experimental surfaces are opt-in**: `things reorder` (ordering within Today, the Inbox, Someday, a project's to-dos, a project's headings, or an area) rides an undocumented AppleScript command that any Things update may remove. It requires `things config set allow-experimental true` and re-checks the app's sdef declaration before every dispatch; `things doctor` reports both gates. Two scopes never touch it: This Evening and the top-level sidebar projects use verified `when=` round-trips (the "bounce", ≤10 items) instead. Reordering the areas themselves (the sidebar order) is a separate operation on the Accessibility GUI vector (`things area reorder`, MCP `reorder` with `scope=areas`).
81
+ 7. **Consumer timezone (optional)**: date boundaries (today / evening / upcoming / logbook sweep / overdue / since-until) evaluate in the host's zone by default. Set `THINGS_TZ` (an IANA zone) so they render for another calendar — e.g. an always-on Mac queried three zones away; over MCP the date-sensitive read tools and the `when`-bearing write tools also take a per-call `tz` that overrides it. `THINGS_NOW` (an ISO instant) pins "now" for determinism. When either is in effect a response carries `meta.clock { timezone, today }` (absent on the host clock); invalid values fail closed (exit 2). Writing `when` = today resolves to that zone's date before dispatch; `when` = evening is refused when the consumer's day differs from the app machine's (This Evening exists only for the app machine's current day). Reminder times are wall-clock and never shifted. For a dedicated single-consumer host, aligning the system timezone (`sudo systemsetup -settimezone <zone>`) is the simpler path — see [docs/design/contracts.md](docs/design/contracts.md#deployment-note--host-timezone-alignment).
70
82
 
71
83
  A typical mutation flow:
72
84
 
@@ -83,6 +95,28 @@ things undo # execute it — verified like an
83
95
 
84
96
  Failure modes are first-class: a `verify-failed:silent-noop` means the app accepted the command and did nothing (a real Things behavior the guards mostly prevent — see [docs/things-app-oddities.md](docs/things-app-oddities.md)); `blocked:*` responses include machine-readable remediation.
85
97
 
98
+ ## Agent skill
99
+
100
+ An [agent skill](skills/things-cli/SKILL.md) ships in the package: a compact orientation an agent loads once — the data model, how to refer to items, and the stable machine contracts — pointing at `things --help` and `things help <topic>` for the fast-moving mechanics. **Install the skill and the rest self-maintains:** CLI access is via whatever `things` (or `npx`) resolves, mechanics come from that binary's own help, and version nudges flow both ways.
101
+
102
+ Install (or update) it with one command:
103
+
104
+ ```sh
105
+ things install-skill # global: covers every agent harness the skills CLI detects
106
+ things install-skill --project # into the current project's .agents instead
107
+ things install-skill --check # compare installed vs this binary's version, write nothing
108
+ ```
109
+
110
+ Under the hood it hands the bundled skill to the [`skills` CLI](https://github.com/vercel-labs/skills) (`npx -y skills add …`), which keeps one canonical copy under `~/.agents/skills/` and materializes it into each detected agent's directory (`~/.claude/skills/`, `~/.codex/skills/`, …). When that tool or the network is unavailable it falls back to a plain copy into `~/.agents` and `~/.claude`. **Re-running `things install-skill` IS the update** — it replaces the skill wholesale — so prefer it over a generic `skills update` for this skill (a single, unambiguous update path).
111
+
112
+ Three entry angles, all converging on the same working setup:
113
+
114
+ - **CLI installed** (`npm i -g things-api`) → `things --help` suggests `things install-skill`.
115
+ - **No install** → `npx things-api install-skill` places the skill; the skill itself falls back to `npx -y things-api@latest` for every command, so it works with no global binary on PATH.
116
+ - **Skill first, zero npm knowledge** → `npx skills add mikegreiling/things-api` pulls the skill straight from GitHub (whatever `skills/things-cli/` currently holds).
117
+
118
+ To keep the two sides from drifting, `install-skill` stamps the copy it places with the running binary's own version, and (on human/`--help` output only, never `--json`) the binary notes when the installed skill is well behind that version. That notice reads the well-known skill directories under `~/.agents` and `~/.claude`; disable it with `THINGS_API_NO_SKILL_CHECK=1`.
119
+
86
120
  ## Architecture: one library, thin surfaces
87
121
 
88
122
  The TypeScript library (`import { openThings } from "things-api"`) is the product; the CLI and the MCP server are thin presentation layers over the same `ThingsClient` — every read view and every verified mutation is a client method first. Shared machine contracts (JSON envelope, exit codes) live in the core (`contracts.ts`), and `diagnose()` / `capabilitiesTable()` are library functions the surfaces merely render.
@@ -97,13 +131,16 @@ The TypeScript library (`import { openThings } from "things-api"`) is the produc
97
131
 
98
132
  The server instructions carry the user's live inventory (areas, tag hierarchy, open projects — read at server start) plus the reference/scheduling vocabulary, so models can name real destinations without a discovery round-trip. Tools mirror the client surface, grouped by area:
99
133
 
134
+ The catalog is consolidated around a few verb-parameterized tools (a discriminator — `kind`, `scope`, or `action` — selects the variant, with per-variant requirements validated at call time). This keeps every capability reachable while shrinking the static tool surface a model must load.
135
+
100
136
  - **Reads**: `read_view` (today / inbox / anytime / upcoming with occurrence horizon / someday / logbook / trash), `search`, `changes_since`, `get_item`, `get_project`, `get_area`, `list_collections`.
101
- - **To-do writes**: `add_todo`, `update_todo`, `set_todo_status`, `move_todo`, `set_tags`, `edit_checklist`, plus completion/creation backdating (`backdate_todo`) and Logbook import (`add_logged_todo`).
102
- - **Project writes**: `add_project`, `update_project`, `set_project_status`, `move_project`.
103
- - **To-dos and projects alike**: `delete_item`, `restore_item`, `duplicate_item`.
104
- - **Areas & tags**: `add_area`, `update_area`, `delete_area`, `add_tag`, `update_tag`, `delete_tag` (tag CRUD incl. un-nesting and guarded subtree deletion).
105
- - **Headings & reminders** (Shortcuts-backed where headless-impossible): `create_heading`, `rename_heading`, `archive_heading`, `unarchive_heading`, `clear_reminder`.
106
- - **Accessibility GUI ("ui") vector** (two-key gated `ui-enabled` config + `dangerously_drive_gui` per call): `make_repeating`, `reschedule_repeat`, `set_repeat_state`, `convert_to_project`, `make_project_repeating`, `create_repeating_project`, `reschedule_project_repeat`, `set_project_repeat_state`, `reorder_area`.
107
- - **Generic & discovery**: `run_operation` (the full 49-op catalog), `batch`, `reorder`, `undo`, `capabilities`, `doctor`.
108
-
109
- Every write tool takes `dry_run`; the ui-vector tools additionally require `dangerously_drive_gui`; tools carry read-only/destructive annotations; hazard blocks come back as structured tool errors carrying the same remediation text the CLI prints. Tool descriptions follow the consumer-voice contract in [docs/design/surface-copy.md](docs/design/surface-copy.md).
137
+ - **Editing**: `update` (`kind` todo / project / area / tag), `set_status` (`scope` todo / project — completed / canceled / open, with the project children policy), `delete` (`kind` item / area / tag — Trash for items, guarded permanent delete for areas/tags incl. tag subtrees).
138
+ - **To-do writes**: `add_todo`, `move_todo`, `set_tags`, `edit_checklist`, plus completion/creation backdating (`backdate_todo`) and Logbook import (`add_logged_todo`).
139
+ - **Project writes**: `add_project`, `move_project`.
140
+ - **To-dos and projects alike**: `restore_item`, `duplicate_item`.
141
+ - **Create**: `add_area`, `add_tag`.
142
+ - **Headings & reminders** (Shortcuts-backed where headless-impossible): `heading` (`action` create / rename / archive / unarchive / convert_to_project), `clear_reminder`.
143
+ - **Recurrence via the Accessibility GUI ("ui") vector** (two-key gated — `ui-enabled` config + `dangerously_drive_gui` per call): `repeat` (`scope` todo / project; `action` start / reschedule / pause / resume / create). The `heading` convert_to_project action and the `reorder` areas scope ride the same gated GUI surface.
144
+ - **Generic & discovery**: `run_operation` (the full 52-op catalog), `batch`, `reorder` (item ordering across scopes, plus `scope=areas` for the sidebar area order), `undo`, `capabilities`, `doctor`.
145
+
146
+ Every write tool takes `dry_run`; the GUI-driven variants additionally require `dangerously_drive_gui`; tools carry read-only/destructive annotations; hazard blocks come back as structured tool errors carrying the same remediation text the CLI prints. Tool descriptions follow the consumer-voice contract in [docs/design/surface-copy.md](docs/design/surface-copy.md).
@@ -26,6 +26,13 @@ export interface AuditRecord {
26
26
  * apart from a nonexistent one. Absent on ordinary (non-undo) mutations.
27
27
  */
28
28
  undoOf?: string;
29
+ /**
30
+ * Client idempotency id (ADDITIVE): a caller-supplied id for a batch line,
31
+ * recorded so a resubmitted batch can recognize an already-applied line (a
32
+ * later submission with the same `opId` on an `ok` record is skipped instead
33
+ * of re-created). Absent on records with no client idempotency id.
34
+ */
35
+ opId?: string;
29
36
  /** Normalized requested delta (params as given, post-normalization). */
30
37
  requested: Record<string, unknown>;
31
38
  /** Asserted-field subset of the pre-state (null when target didn't exist). */
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/audit/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAkDzC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,SAAS,CACvB,MAA0E;IAE1E,IAAI,MAAM,CAAC,GAAG,EAAE,IAAI,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IACzD,yEAAyE;IACzE,wEAAwE;IACxE,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC;QAC9B,MAAM,CAAC,EAAE;QACT,MAAM,CAAC,EAAE;QACT,MAAM,CAAC,KAAK;QACZ,MAAM,CAAC,IAAI;QACX,MAAM,CAAC,IAAI,IAAI,EAAE;KAClB,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAChF,OAAO,KAAK,MAAM,EAAE,CAAC;AACvB,CAAC"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/audit/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAyDzC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,SAAS,CACvB,MAA0E;IAE1E,IAAI,MAAM,CAAC,GAAG,EAAE,IAAI,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IACzD,yEAAyE;IACzE,wEAAwE;IACxE,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC;QAC9B,MAAM,CAAC,EAAE;QACT,MAAM,CAAC,EAAE;QACT,MAAM,CAAC,KAAK;QACZ,MAAM,CAAC,IAAI;QACX,MAAM,CAAC,IAAI,IAAI,EAAE;KAClB,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAChF,OAAO,KAAK,MAAM,EAAE,CAAC;AACvB,CAAC"}
@@ -0,0 +1,8 @@
1
+ export declare function setRenderClock(clock: {
2
+ now: () => Date;
3
+ zone: string | undefined;
4
+ }): void;
5
+ /** The render clock's instant (pinned THINGS_NOW when set, else real time); host time when unset. */
6
+ export declare function renderNow(): Date;
7
+ /** The render clock's consumer zone, or undefined for the host zone. */
8
+ export declare function renderZone(): string | undefined;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * The CLI's process-wide render clock, resolved once in `runCli` from the
3
+ * environment (THINGS_TZ / THINGS_NOW) and read by the pure renderers and the
4
+ * period parsers — the same module-state pattern the width fit uses
5
+ * (./width.ts). It carries the consumer's `now` source and IANA zone so every
6
+ * human date token (Today marker, ‹date› chips, period bounds) matches the
7
+ * `meta.clock` the library reports. Unset (the default, and in unit tests that
8
+ * import the renderers directly) it is the host clock — byte-identical output.
9
+ */
10
+ let clockNow = null;
11
+ let clockZone;
12
+ export function setRenderClock(clock) {
13
+ clockNow = clock.now;
14
+ clockZone = clock.zone;
15
+ }
16
+ /** The render clock's instant (pinned THINGS_NOW when set, else real time); host time when unset. */
17
+ export function renderNow() {
18
+ return clockNow === null ? new Date() : clockNow();
19
+ }
20
+ /** The render clock's consumer zone, or undefined for the host zone. */
21
+ export function renderZone() {
22
+ return clockZone;
23
+ }
24
+ //# sourceMappingURL=clock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clock.js","sourceRoot":"","sources":["../../src/cli/clock.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,IAAI,QAAQ,GAAwB,IAAI,CAAC;AACzC,IAAI,SAA6B,CAAC;AAElC,MAAM,UAAU,cAAc,CAAC,KAAoD;IACjF,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC;IACrB,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC;AACzB,CAAC;AAED,qGAAqG;AACrG,MAAM,UAAU,SAAS;IACvB,OAAO,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;AACrD,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,UAAU;IACxB,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -3,35 +3,41 @@
3
3
  * under `things area` are registered by writes.ts on the same group).
4
4
  */
5
5
  import type { Command } from "commander";
6
- import { type AreaView, type GroupedLimits, type GroupedTruncation } from "../../index.ts";
6
+ import { type AreaView, type GroupedLimits, type Truncation } from "../../index.ts";
7
7
  import { type TagFlags } from "../tag-filters.ts";
8
8
  export interface AreaShowOpts {
9
9
  showLater?: boolean;
10
- /** Commander optional-value flag: true when bare, the raw string when given a count. */
11
- showLogged?: boolean | string;
12
10
  /**
13
11
  * Per-section caps: `project` bounds the project-ROWS section, `area` the
14
- * direct-to-dos section (null = uncapped). The toggled later/logged
15
- * sections keep their own existing bounds.
12
+ * direct-to-dos section (null = uncapped). The toggled later
13
+ * section keeps its own existing bounds.
16
14
  */
17
15
  limits?: GroupedLimits;
18
16
  /** The user's invocation, echoed by the per-section truncation footers. */
19
17
  hintBase?: string;
18
+ /**
19
+ * The live count of the area's logged rows (subtree-inclusive, past the
20
+ * log-move boundary — the same population `things logbook --area <ref>`
21
+ * returns). Drives the TTY logbook footer's count; omitted / 0 hides the line.
22
+ * TTY-only — the JSON area-view shape never carries it.
23
+ */
24
+ loggedCount?: number | undefined;
20
25
  }
21
26
  /**
22
27
  * GUI layout: active projects first (sidebar order), then the area's direct
23
28
  * to-dos. `--show-later` reveals the GUI's toggled sections — Upcoming
24
29
  * (future-scheduled projects, to-dos, and repeating templates intermixed in
25
30
  * date order) and Someday (someday projects as a leading block, then
26
- * someday to-dos). `--show-logged` reveals the full logbook.
31
+ * someday to-dos). The area logbook is NOT a view section — it is the bounded
32
+ * query `things logbook --area <ref>`; trashed rows live in `things trash`.
27
33
  *
28
34
  * `view` is the already-bounded card (its ACTIVE project rows and direct to-dos
29
- * capped; scheduled/someday project rows and the later/logged/trashed sections
30
- * intact) and `grouped` the per-block metadata carrying each capped section's
31
- * pre-cap total — so the "… N more" footers derive from metadata, never a
32
- * pre-cap copy of the view.
35
+ * capped; scheduled/someday project rows and the later section intact) and
36
+ * `grouped` the per-block metadata carrying each capped section's pre-cap total
37
+ * — so the "… N more" footers derive from metadata, never a pre-cap copy of the
38
+ * view.
33
39
  */
34
- export declare function renderAreaView(view: AreaView, grouped: GroupedTruncation, opts: AreaShowOpts): string[];
40
+ export declare function renderAreaView(view: AreaView, truncation: Truncation, opts: AreaShowOpts): string[];
35
41
  /** Options accepted by the area-show code path (shared by `area show` and `areas <ref>`). */
36
42
  export type AreaShowActionOpts = AreaShowOpts & TagFlags & {
37
43
  json?: boolean;
@@ -40,6 +46,7 @@ export type AreaShowActionOpts = AreaShowOpts & TagFlags & {
40
46
  areaLimit?: string;
41
47
  projectLimit?: string;
42
48
  all?: boolean;
49
+ full?: boolean;
43
50
  /** Content scope: keep only rows (loose to-dos + child projects) with an overdue own deadline. */
44
51
  overdue?: boolean;
45
52
  };
@@ -1,38 +1,30 @@
1
1
  import { bold, dim, green } from "../style.js";
2
2
  import { areaMark, thingsLink } from "../glyphs.js";
3
3
  import { Option } from "commander";
4
- import { openInThings } from "./reads.js";
4
+ import { openInThings, revealLine } from "./reads.js";
5
+ import { renderNow, renderZone } from "../clock.js";
5
6
  import { invocation, parseCap, runRead, shellQuote, usageError, withClient, } from "../read-driver.js";
6
7
  import { disclosureHint, formatItem, quoteTitle, uuidDisplayWidth } from "../render.js";
7
8
  import { DidYouMeanError } from "../did-you-mean.js";
8
9
  import { showToggleFlags } from "./project.js";
9
- import { AREA_PREVIEW_LIMIT, GROUPED_ALL_DESC, isActiveProjectRow, isScheduledProjectRow, isSomedayProjectRow, localToday, } from "../../index.js";
10
+ import { AREA_PREVIEW_LIMIT, FULL_DESC, GROUPED_ALL_DESC, isLooseRef, LOOSE_OPEN_REFUSAL, isActiveProjectRow, isScheduledProjectRow, isSomedayProjectRow, localToday, } from "../../index.js";
10
11
  import { addTagFilterOptions, CONTAINER_TAG_HINT, tagFilterFields, tagFlagConflict, tagInvocationParts, } from "../tag-filters.js";
11
- /** Bare `--show-logged` shows this many recent entries (areas accumulate thousands). */
12
- const RECENT_LOGGED_DEFAULT = 15;
13
- function loggedCount(showLogged) {
14
- if (showLogged === undefined)
15
- return 0;
16
- if (showLogged === true)
17
- return RECENT_LOGGED_DEFAULT;
18
- const n = Number(showLogged);
19
- return Number.isInteger(n) && n > 0 ? n : RECENT_LOGGED_DEFAULT;
20
- }
21
12
  /**
22
13
  * GUI layout: active projects first (sidebar order), then the area's direct
23
14
  * to-dos. `--show-later` reveals the GUI's toggled sections — Upcoming
24
15
  * (future-scheduled projects, to-dos, and repeating templates intermixed in
25
16
  * date order) and Someday (someday projects as a leading block, then
26
- * someday to-dos). `--show-logged` reveals the full logbook.
17
+ * someday to-dos). The area logbook is NOT a view section — it is the bounded
18
+ * query `things logbook --area <ref>`; trashed rows live in `things trash`.
27
19
  *
28
20
  * `view` is the already-bounded card (its ACTIVE project rows and direct to-dos
29
- * capped; scheduled/someday project rows and the later/logged/trashed sections
30
- * intact) and `grouped` the per-block metadata carrying each capped section's
31
- * pre-cap total — so the "… N more" footers derive from metadata, never a
32
- * pre-cap copy of the view.
21
+ * capped; scheduled/someday project rows and the later section intact) and
22
+ * `grouped` the per-block metadata carrying each capped section's pre-cap total
23
+ * — so the "… N more" footers derive from metadata, never a pre-cap copy of the
24
+ * view.
33
25
  */
34
- export function renderAreaView(view, grouped, opts) {
35
- const todayIso = localToday();
26
+ export function renderAreaView(view, truncation, opts) {
27
+ const todayIso = localToday(renderNow(), renderZone());
36
28
  // The card's ACTIVE project rows are already capped in `view`; scheduled and
37
29
  // someday rows always survive and route to the Upcoming/Someday sections.
38
30
  const activeProjects = view.projects.filter((p) => isActiveProjectRow(p, todayIso));
@@ -43,32 +35,34 @@ export function renderAreaView(view, grouped, opts) {
43
35
  ...view.projects
44
36
  .filter((p) => isScheduledProjectRow(p, todayIso))
45
37
  .map((p) => ({ date: p.startDate ?? "", item: p })),
46
- ...view.later.scheduled.flatMap((d) => d.items.map((t) => ({ date: d.date, item: t }))),
47
- ...view.later.repeating.map((t) => ({ date: t.repeating.nextOccurrence ?? "9999", item: t })),
38
+ ...view.scheduled.flatMap((d) => d.items.map((t) => ({ date: d.date, item: t }))),
39
+ ...view.repeating.map((t) => ({ date: t.repeating.nextOccurrence ?? "9999", item: t })),
48
40
  ].toSorted((a, b) => a.date.localeCompare(b.date));
49
- const logged = view.logged.slice(0, loggedCount(opts.showLogged));
50
41
  const shown = [
51
42
  ...activeProjects,
52
43
  ...view.active,
53
44
  ...(opts.showLater === true
54
- ? [...upcoming.map((u) => u.item), ...somedayProjects, ...view.later.someday]
45
+ ? [...upcoming.map((u) => u.item), ...somedayProjects, ...view.someday]
55
46
  : []),
56
- ...logged,
57
47
  ];
58
48
  const w = uuidDisplayWidth(shown);
59
49
  // Per-section caps (this view's sections are containers, so there is no
60
50
  // strict total limit): the project-ROWS block and the direct-to-dos block
61
51
  // truncate independently, each with its own exact-count footer. The card
62
- // preamble and the toggled later/logged sections are never capped. The pre-cap
52
+ // preamble and the toggled later section are never capped. The pre-cap
63
53
  // totals come from the metadata; `limits` supplies the footer's doubling.
64
54
  const limits = opts.limits ?? { area: null, project: null };
65
- const projectsBlock = grouped.blocks.find((b) => b.kind === "projects");
66
- const activeBlock = grouped.blocks.find((b) => b.kind === "area");
55
+ const projectsBlock = truncation.blocks?.find((b) => b.kind === "projects");
56
+ const activeBlock = truncation.blocks?.find((b) => b.kind === "area");
67
57
  const hiddenProjects = projectsBlock ? projectsBlock.total - projectsBlock.shown : 0;
68
58
  const hiddenActive = activeBlock ? activeBlock.total - activeBlock.shown : 0;
59
+ // The `loose` pseudo-area renders like an area card but has no uuid/uri/tags
60
+ // (the NULL area is a derived view).
61
+ const isLoose = view.area === null;
62
+ const areaTitle = view.area?.title ?? "Loose";
69
63
  // The user's invocation, echoed by every disclosure hint (falls back to a
70
64
  // canonical typed command when a caller omits it, e.g. a direct unit test).
71
- const base = opts.hintBase ?? `things area show ${quoteTitle(view.area.title)}`;
65
+ const base = opts.hintBase ?? `things area show ${isLoose ? "loose" : quoteTitle(areaTitle)}`;
72
66
  // A per-block TRUNCATION FOOTER (indented two spaces under its partially-
73
67
  // shown block): ` … N more <noun>s — `<base> <flag> <bigger>``.
74
68
  const sectionMore = (hidden, noun, flag, cap) => {
@@ -83,17 +77,17 @@ export function renderAreaView(view, grouped, opts) {
83
77
  // group in this view), so they get the bold project title from delta 1 but NO
84
78
  // underline; only ANYTIME treats projects as headings. So a project renders
85
79
  // exactly like any other row here — no projectTitle opt.
86
- const fmt = (i) => formatItem(i, w, { suppressArea: view.area.uuid });
80
+ const fmt = (i) => formatItem(i, w, { suppressArea: view.area?.uuid ?? null });
87
81
  const fmtProject = fmt;
88
82
  // Card header: glyph + name, the GUI's share link (carries the uuid — it
89
83
  // pastes back into any ref argument), then labeled meta lines. The opened
90
84
  // resource shows its tags green (GUI: list pills are gray).
91
- const lines = [
92
- `${bold("Area:")} ${areaMark()} ${bold(view.area.title)}`,
93
- ` ${dim("uri:")} ${thingsLink(view.area.uuid)}`,
94
- ];
95
- if (view.area.tags.length > 0)
96
- lines.push(` ${dim("tags:")} ${green(`#${view.area.tags.map((t) => t.title).join(" #")}`)}`);
85
+ const lines = [`${bold("Area:")} ${areaMark()} ${bold(areaTitle)}`];
86
+ if (view.area !== null) {
87
+ lines.push(` ${dim("uri:")} ${thingsLink(view.area.uuid)}`);
88
+ if (view.area.tags.length > 0)
89
+ lines.push(` ${dim("tags:")} ${green(`#${view.area.tags.map((t) => t.title).join(" #")}`)}`);
90
+ }
97
91
  const block = (rows) => {
98
92
  if (rows.length > 0)
99
93
  lines.push("", ...rows);
@@ -108,48 +102,31 @@ export function renderAreaView(view, grouped, opts) {
108
102
  if (upcoming.length > 0) {
109
103
  lines.push("", bold("── Upcoming ──"), ...upcoming.map((u) => fmt(u.item)));
110
104
  }
111
- if (somedayProjects.length > 0 || view.later.someday.length > 0) {
105
+ if (somedayProjects.length > 0 || view.someday.length > 0) {
112
106
  lines.push("", bold("── Someday ──"), ...somedayProjects.map(fmtProject));
113
- if (view.later.someday.length > 0) {
107
+ if (view.someday.length > 0) {
114
108
  if (somedayProjects.length > 0)
115
109
  lines.push("");
116
- lines.push(...view.later.someday.map(fmt));
110
+ lines.push(...view.someday.map(fmt));
117
111
  }
118
112
  }
119
113
  }
120
114
  // Default-hidden rows are never silent — a HIDDEN-SECTION placeholder (flush,
121
115
  // full command) stands where the Upcoming/Someday sections would render.
122
116
  if (opts.showLater !== true) {
123
- const hiddenLater = upcoming.length + somedayProjects.length + view.later.someday.length;
117
+ const hiddenLater = upcoming.length + somedayProjects.length + view.someday.length;
124
118
  if (hiddenLater > 0)
125
119
  lines.push("", disclosureHint(hiddenLater, "later item", [{ command: `${base} --show-later` }]));
126
120
  }
127
- // The full archive belongs to `things logbook --area <ref>` echoed
128
- // ready-to-paste with the real area name, like every other drill hint.
129
- const logbookCmd = `things logbook --area ${quoteTitle(view.area.title)}`;
130
- if (logged.length > 0) {
131
- // Truncation is loud: areas accumulate years of history. The header keeps
132
- // the shown-of-total count for orientation; the actionable drill rides a
133
- // section footer (matching the other truncated sections), never the header.
134
- const more = view.logged.length - logged.length;
135
- const header = more > 0
136
- ? `── Logged (${logged.length} of ${view.logged.length}) ──`
137
- : `── Logged (${view.logged.length}) ──`;
138
- lines.push("", bold(header), ...logged.map(fmt));
139
- if (more > 0)
140
- lines.push(dim(`… ${more} more — \`${logbookCmd}\``));
141
- }
142
- else if (view.logged.length > 0) {
143
- // Hidden-section placeholder: `--show-logged` reveals only the RECENT 15
144
- // (areas accumulate years), so it is labeled; the logbook drill reads its
145
- // own effect and needs none.
146
- lines.push("", disclosureHint(view.logged.length, "logged item", [
147
- { label: "recent", command: `${base} --show-logged` },
148
- { command: logbookCmd },
149
- ]));
121
+ // The area logbook is not a card sectionit is the bounded query
122
+ // `things logbook --area <ref>` (a real area only; the loose pseudo-area
123
+ // accumulates no `logbook --area` archive). Trashed rows live in
124
+ // `things trash`. The footer carries a LIVE count of that archive; it is
125
+ // omitted entirely when the area has logged nothing (count 0 → no pointer).
126
+ const loggedCount = opts.loggedCount ?? 0;
127
+ if (!isLoose && loggedCount > 0) {
128
+ lines.push("", dim(`${loggedCount.toLocaleString("en-US")} logged item${loggedCount === 1 ? "" : "s"} — \`things logbook --area ${quoteTitle(areaTitle)}\``));
150
129
  }
151
- if (view.trashed.length)
152
- lines.push("", bold(`── Trashed (${view.trashed.length}) ──`));
153
130
  return lines;
154
131
  }
155
132
  /**
@@ -198,8 +175,14 @@ export function runAreaShow(ref, opts) {
198
175
  }
199
176
  return {
200
177
  data: bounded.view,
201
- grouped: bounded.grouped,
202
- lines: renderAreaView(bounded.view, bounded.grouped, { ...opts, limits, hintBase }),
178
+ truncation: bounded.truncation,
179
+ ...(bounded.notice !== undefined && { warnings: [bounded.notice] }),
180
+ lines: renderAreaView(bounded.view, bounded.truncation, {
181
+ ...opts,
182
+ limits,
183
+ hintBase,
184
+ loggedCount: bounded.loggedCount,
185
+ }),
203
186
  };
204
187
  }, () => []);
205
188
  }
@@ -209,16 +192,16 @@ export function registerAreaCommands(program) {
209
192
  .command("show <ref>")
210
193
  .description("Composite area view mirroring the native UI: active projects first, then the " +
211
194
  "area's direct to-dos. --show-later adds the Upcoming (date-ordered) and " +
212
- "Someday sections; --show-logged adds the full logbook. --tag / --untagged filter " +
213
- "the rows by a tag carried directly on the row tags inherited from this area are " +
214
- "ignored (every row inherits them); no descent into project contents. Target by " +
215
- "uuid or unique name.")
195
+ "Someday sections. The area logbook is not a section here read it with " +
196
+ "`things logbook --area <ref>`. Tag filters match rows directly and never " +
197
+ "descend into project contents. Target by uuid or unique name, or the reserved " +
198
+ "word `loose` for the area-less items (the null-area composite).")
216
199
  .option("--show-later", "include Upcoming and Someday sections")
217
- .option("--show-logged [n]", "include the n most recently logged items (bare flag = 15; full history via `things logbook --area`)")
218
200
  .option("--project-limit <n>", `maximum project rows to show (default ${AREA_PREVIEW_LIMIT})`)
219
201
  .option("--area-limit <n>", `maximum direct to-dos to show (default ${AREA_PREVIEW_LIMIT})`)
220
202
  .option("--overdue", "only rows whose own deadline is past (due today is not overdue)")
221
203
  .option("--all", GROUPED_ALL_DESC)
204
+ .option("--full", FULL_DESC)
222
205
  .addOption(new Option("--limit <n>").hideHelp())
223
206
  .option("--json", "emit versioned JSON envelope on stdout")
224
207
  .option("--db <path>", "explicit database path");
@@ -227,16 +210,20 @@ export function registerAreaCommands(program) {
227
210
  .action((ref, opts) => runAreaShow(ref, opts));
228
211
  area
229
212
  .command("open <ref>")
230
- .description("Open the area in the Things app — foregrounds the GUI on this Mac (NOT headless). Errors when the reference is not an area.")
213
+ .description("Open the area in the Things app on this Mac (brings the window forward). Errors if the reference is not an area.")
231
214
  .option("--json", "emit versioned JSON envelope on stdout")
232
215
  .option("--db <path>", "explicit database path")
233
216
  .action((ref, opts) => {
234
217
  withClient(opts, "open", (c) => {
218
+ // The loose pseudo-area is a derived view — refuse by name, not a
219
+ // generic no-such-area error.
220
+ if (isLooseRef(ref))
221
+ throw new RangeError(LOOSE_OPEN_REFUSAL);
235
222
  const t = c.read.showTarget(ref);
236
223
  if (t.kind !== "area")
237
224
  throw new RangeError(`"${ref}" is a ${t.viaHeading === true ? "heading" : t.kind}, not an area (try \`things open\`)`);
238
- return { uri: openInThings(t.uuid) };
239
- }, (d) => [`opened ${d.uri}`]);
225
+ return openInThings(t.uuid, opts.db);
226
+ }, (d) => [revealLine(d)]);
240
227
  });
241
228
  }
242
229
  //# sourceMappingURL=area.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"area.js","sourceRoot":"","sources":["../../../src/cli/commands/area.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"area.js","sourceRoot":"","sources":["../../../src/cli/commands/area.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,6 @@
3
3
  * Exit codes: 0 healthy; 5 drift/unknown-version; 7 environment problems.
4
4
  */
5
5
  import type { Command } from "commander";
6
- import { type DiagnoseReport, type DiagnoseResult } from "../../index.ts";
7
- export type DoctorReport = DiagnoseReport;
6
+ import { type DiagnoseResult } from "../../index.ts";
8
7
  export declare const runDoctor: (dbPath?: string) => DiagnoseResult;
9
8
  export declare function registerDoctor(program: Command): void;
@@ -1,4 +1,5 @@
1
1
  import { describeEnvironmentChanges, diagnose, errorEnvelope, okEnvelope, } from "../../index.js";
2
+ // Back-compat alias for pre-seam consumers of the CLI module.
2
3
  export const runDoctor = diagnose;
3
4
  function environmentLine(env) {
4
5
  if (env.lastVerifiedWrite === null) {
@@ -70,8 +71,17 @@ export function registerDoctor(program) {
70
71
  `db version: ${report.db.databaseVersion ?? "unknown"}`,
71
72
  `fingerprint: ${report.fingerprint.status} (${report.fingerprint.value.slice(0, 23)}…)`,
72
73
  ...report.fingerprint.detail.map((d) => ` drift: ${d}`),
73
- `app: ${report.app.installed ? "installed" : "NOT INSTALLED"}`,
74
+ `app: ${report.app.installed ? "installed" : "NOT INSTALLED"}${report.app.version !== null ? ` (Things ${report.app.version})` : ""}`,
75
+ ...(report.app.behavioralDrift
76
+ ? [
77
+ `behavioral: Things ${report.app.version} installed; behavioral laws last ` +
78
+ `certified against ${report.app.certifiedVersion} — run the drift suite to ` +
79
+ "re-certify (docs/lab/drift-runbook.md). Schema fingerprint is unaffected; " +
80
+ "writes stay enabled",
81
+ ]
82
+ : []),
74
83
  `writes: ${report.writes.enabled ? "enabled" : "DISABLED"} — ${report.writes.reason}`,
84
+ `scope: ${report.scope.detail}`,
75
85
  `experimental: ${report.experimental.reason}`,
76
86
  `environment: ${environmentLine(report.environment)}`,
77
87
  `automation: ${report.automation.status}${report.automation.status === "granted" ? "" : ` — ${report.automation.detail}`}`,