things-api 0.20.0 → 0.20.1

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 (37) hide show
  1. package/README.md +1 -1
  2. package/deputy/prebuilt/Things API Helper.app/Contents/CodeResources +0 -0
  3. package/deputy/prebuilt/Things API Helper.app/Contents/Helpers/things-reader.app/Contents/MacOS/things-reader +0 -0
  4. package/deputy/prebuilt/Things API Helper.app/Contents/MacOS/things-deputy +0 -0
  5. package/dist/cli/help.js +1 -1
  6. package/dist/contracts.d.ts +1 -1
  7. package/dist/contracts.js +1 -1
  8. package/dist/model/mappers.js +11 -9
  9. package/dist/model/mappers.js.map +1 -1
  10. package/dist/model/today-placement.d.ts +65 -0
  11. package/dist/model/today-placement.js +59 -0
  12. package/dist/model/today-placement.js.map +1 -0
  13. package/dist/write/commands.js +3 -1
  14. package/dist/write/commands.js.map +1 -1
  15. package/dist/write/disclosures.d.ts +12 -0
  16. package/dist/write/disclosures.js +12 -0
  17. package/dist/write/disclosures.js.map +1 -1
  18. package/dist/write/guards.js +28 -5
  19. package/dist/write/guards.js.map +1 -1
  20. package/dist/write/move.js +33 -6
  21. package/dist/write/move.js.map +1 -1
  22. package/dist/write/pipeline.js +49 -4
  23. package/dist/write/pipeline.js.map +1 -1
  24. package/dist/write/pre-state.d.ts +9 -9
  25. package/dist/write/pre-state.js +44 -38
  26. package/dist/write/pre-state.js.map +1 -1
  27. package/dist/write/reorder.js +28 -7
  28. package/dist/write/reorder.js.map +1 -1
  29. package/dist/write/vectors/types.d.ts +10 -0
  30. package/dist/write/vectors/ui-drag.d.ts +102 -0
  31. package/dist/write/vectors/ui-drag.js +425 -11
  32. package/dist/write/vectors/ui-drag.js.map +1 -1
  33. package/dist/write/vectors/ui.d.ts +6 -0
  34. package/dist/write/vectors/ui.js +33 -1
  35. package/dist/write/vectors/ui.js.map +1 -1
  36. package/package.json +1 -1
  37. package/skills/things-cli/SKILL.md +1 -1
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  A typed TypeScript library + CLI (`things`) for programmatic interaction with [Things 3](https://culturedcode.com/things/) by Cultured Code.
6
6
 
7
- **Status: read + write + MCP layers live and published to npm (v0.20.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 kind-neutral in-place reordering within any container or view (one `things reorder <refs…> [--start|--end|--before|--after] --in <target>` verb — Today/Evening, a project, an area, a heading's children, someday, inbox — plus `project move-heading` for the headings themselves and `area reorder` for the sidebar). The Apple Shortcuts surface is wired for the two headless capabilities nothing else can do: creating a heading in an existing project (`things project add-heading`) and clearing a reminder from a date-scheduled item (`things todo clear-reminder`). Both run through bundled proxy shortcuts (`things setup`) 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.
7
+ **Status: read + write + MCP layers live and published to npm (v0.20.1 — 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 kind-neutral in-place reordering within any container or view (one `things reorder <refs…> [--start|--end|--before|--after] --in <target>` verb — Today/Evening, a project, an area, a heading's children, someday, inbox — plus `project move-heading` for the headings themselves and `area reorder` for the sidebar). The Apple Shortcuts surface is wired for the two headless capabilities nothing else can do: creating a heading in an existing project (`things project add-heading`) and clearing a reminder from a date-scheduled item (`things todo clear-reminder`). Both run through bundled proxy shortcuts (`things setup`) 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.
8
8
 
9
9
  ```sh
10
10
  things today --json # read: your Today list, Evening split, UI order
package/dist/cli/help.js CHANGED
@@ -403,7 +403,7 @@ repeater), \`… add-repeating "<title>"\` (create + make repeating in one call)
403
403
  <daily|weekly|monthly|yearly>\` and \`--interval <n>\` (1 = every unit). These drive the
404
404
  app's Repeat dialog, so they require \`--dangerously-drive-gui\`, \`--dry-run\` included.
405
405
 
406
- MOVING a series: \`reschedule-repeat <ref> --when <date>\` with NO --frequency/--interval
406
+ RE-DATING a series: \`reschedule-repeat <ref> --when <date>\` with NO --frequency/--interval
407
407
  keeps the rule and needs no --dangerously-drive-gui. The WHOLE series moves (weekly → a
408
408
  Thursday repeats on Thursdays), occurrences due before that date are skipped, and it
409
409
  cannot be undone here. Refused for a date not after today, a paused, --after-completion
@@ -14,7 +14,7 @@ export declare const API_VERSION = 1;
14
14
  * Package version, surfaced by `things --version` and the MCP serverInfo.
15
15
  * Kept in lockstep with package.json by a contract test.
16
16
  */
17
- export declare const PKG_VERSION = "0.20.0";
17
+ export declare const PKG_VERSION = "0.20.1";
18
18
  /**
19
19
  * Stable exit-code contract for the `things` CLI (mirrored by MCP error
20
20
  * codes). Part of the public API surface consumed by agents and scripts —
package/dist/contracts.js CHANGED
@@ -13,7 +13,7 @@ export const API_VERSION = 1;
13
13
  * Package version, surfaced by `things --version` and the MCP serverInfo.
14
14
  * Kept in lockstep with package.json by a contract test.
15
15
  */
16
- export const PKG_VERSION = "0.20.0";
16
+ export const PKG_VERSION = "0.20.1";
17
17
  /**
18
18
  * Stable exit-code contract for the `things` CLI (mirrored by MCP error
19
19
  * codes). Part of the public API surface consumed by agents and scripts —
@@ -5,6 +5,7 @@
5
5
  import { START_STATE_FROM_DB, TASK_STATUS_FROM_DB, } from "./entities.js";
6
6
  import { decodeEpochReal, decodePackedDate, decodeReminderTime } from "./dates.js";
7
7
  import { templateProjectionDay } from "./template-projection.js";
8
+ import { todayPlacement } from "./today-placement.js";
8
9
  import { reminderIsLive } from "../read/stage.js";
9
10
  export class EnumDomainError extends RangeError {
10
11
  constructor(field, value, uuid) {
@@ -66,26 +67,27 @@ function mapRepeating(row) {
66
67
  * agrees with the view: a SCHEDULED arm (a `startDate <= today` on a start=active
67
68
  * or start=someday row) OR a DEADLINE arm (an undated row whose deadline is
68
69
  * due/overdue and not dismissed — the `deadlineSuppressionDate` guard, oddities
69
- * §8e). Evening is the This-Evening sub-section (`startBucket=1` AND `startDate`
70
- * exactly today), and implies today. Repeating templates are never in Today
71
- * (the view excludes them), so they never mark. The closed-and-swept (logged)
72
- * gate is applied downstream at the emit boundary (which knows `stage`), since
73
- * the logbook boundary is not visible here.
70
+ * §8e). Evening is the This-Evening sub-section, derived by the ONE placement law
71
+ * ({@link todayPlacement}) the reorder scopes and the move planner also consult —
72
+ * so a STALE evening row (`startBucket=1` whose day has passed) marks `today`,
73
+ * never `evening`, exactly as the app renders it. Repeating templates are never
74
+ * in Today (the view excludes them), so they never mark. The closed-and-swept
75
+ * (logged) gate is applied downstream at the emit boundary (which knows `stage`),
76
+ * since the logbook boundary is not visible here.
74
77
  */
75
78
  function todayMarkers(row, packedToday) {
76
79
  const isTemplate = row.rt1_recurrenceRule !== null || row.repeater !== null;
77
80
  if (isTemplate)
78
81
  return {};
79
82
  const start = row.start ?? 0;
80
- const scheduledArm = row.startDate !== null && row.startDate <= packedToday && (start === 1 || start === 2);
83
+ const placement = todayPlacement({ start, startDate: row.startDate, startBucket: row.startBucket }, packedToday);
81
84
  const deadlineArm = row.startDate === null &&
82
85
  row.deadline !== null &&
83
86
  row.deadline <= packedToday &&
84
87
  (row.deadlineSuppressionDate === null || row.deadlineSuppressionDate < row.deadline);
85
- if (!scheduledArm && !deadlineArm)
88
+ if (placement === null && !deadlineArm)
86
89
  return {};
87
- const evening = row.startBucket === 1 && start === 1 && row.startDate === packedToday;
88
- return evening ? { today: true, evening: true } : { today: true };
90
+ return placement === "evening" ? { today: true, evening: true } : { today: true };
89
91
  }
90
92
  function commonFields(row, refs, tags, packedToday) {
91
93
  const startDate = decodePackedDate(row.startDate);
@@ -1 +1 @@
1
- {"version":3,"file":"mappers.js","sourceRoot":"","sources":["../../src/model/mappers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mappers.js","sourceRoot":"","sources":["../../src/model/mappers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * THE Today / This-Evening placement law — one derivation, every surface.
3
+ *
4
+ * Things stores a Today member's evening flag as a raw `startBucket` byte, and it
5
+ * NEVER cleans that byte when the day it belongs to goes past ([SIT3
6
+ * REMSTALE](../../docs/lab/sit3-arrival-evening-lists.md), oddities §9n). The app
7
+ * instead re-derives placement at RENDER time against the device's current local
8
+ * day, so a `startBucket=1` row whose `startDate` has passed — a STALE evening
9
+ * row — renders in **Today proper**, below the day's daytime rows and ABOVE the
10
+ * "This Evening" section header, exactly like any other arrived member
11
+ * ([STEV1](../../docs/lab/stev1-stale-evening.md) cell 1).
12
+ *
13
+ * Every consumer of the evening flag therefore has to apply the same gate, and
14
+ * they must all apply the SAME one: the read views, the reorder scopes' member
15
+ * census, the bounce's concurrent-edit re-check, and the move planner's axis
16
+ * choice. Four independent spellings is what left a stale evening item refused by
17
+ * BOTH reorder scopes (#657) — `--in today` called it an evening-bucket item and
18
+ * `--in evening` called it stale. This module is the single spelling.
19
+ */
20
+ /**
21
+ * Where a row sits in the Today view: `"today"` (the daytime section),
22
+ * `"evening"` (the This Evening section), or `null` (not a Today member on the
23
+ * scheduled arm at all).
24
+ */
25
+ export type TodayPlacement = "today" | "evening" | null;
26
+ /** The columns the placement law reads. */
27
+ export interface TodayPlacementRow {
28
+ /** `start`: 0 = inbox, 1 = anytime/active, 2 = someday. */
29
+ start: number;
30
+ /** Packed `startDate`, or null for an undated row. */
31
+ startDate: number | null;
32
+ /** Raw `startBucket`: 0 = Today proper, 1 = This Evening. */
33
+ startBucket: number | null;
34
+ }
35
+ /**
36
+ * The Today/Evening placement of a row on the SCHEDULED arm, under `packedToday`
37
+ * (the device-local day, encoded — never a UTC date; see
38
+ * [timezones](../../docs/reference/timezones.md)).
39
+ *
40
+ * - An Inbox row (`start=0`) is never a scheduled Today member.
41
+ * - An undated or strictly-future row is not a member either.
42
+ * - An ARRIVED row (`startDate <= today`, `start` 1 or 2) IS a Today member — an
43
+ * overdue day and an arrived someday-scheduled row included.
44
+ * - It is in **This Evening** only while its evening flag is LIVE: `startBucket=1`
45
+ * with a `startDate` of EXACTLY today. Evening membership expires daily, so a
46
+ * past-dated bucket-1 row is `"today"`.
47
+ *
48
+ * Arrivedness is judged on the DATE alone, never on the start state: an arrived
49
+ * someday-scheduled row (`start=2`, `startDate <= today`) is a Today member and
50
+ * buckets today/evening like any other, matching how `deriveStage` reports it as
51
+ * `anytime` carrying the Today marker (#325).
52
+ *
53
+ * The DEADLINE arm of Today membership (an undated row pulled in by a due or
54
+ * overdue deadline) is not expressible from these three columns and is layered on
55
+ * by the reader (`mappers.todayMarkers`); it is never an evening member.
56
+ */
57
+ export declare function todayPlacement(row: TodayPlacementRow, packedToday: number): TodayPlacement;
58
+ /**
59
+ * Whether a row's evening flag has gone STALE: the `startBucket=1` byte is still
60
+ * set, but the day it was set for has passed, so the app renders the row in Today
61
+ * proper. The reorder scopes use this to tell a stale movee (accepted by the
62
+ * `today` scope) from a live evening one (refused there, O03), and to point a
63
+ * stale movee's `evening`-scope refusal at the scope that does take it.
64
+ */
65
+ export declare function isStaleEvening(row: TodayPlacementRow, packedToday: number): boolean;
@@ -0,0 +1,59 @@
1
+ /**
2
+ * THE Today / This-Evening placement law — one derivation, every surface.
3
+ *
4
+ * Things stores a Today member's evening flag as a raw `startBucket` byte, and it
5
+ * NEVER cleans that byte when the day it belongs to goes past ([SIT3
6
+ * REMSTALE](../../docs/lab/sit3-arrival-evening-lists.md), oddities §9n). The app
7
+ * instead re-derives placement at RENDER time against the device's current local
8
+ * day, so a `startBucket=1` row whose `startDate` has passed — a STALE evening
9
+ * row — renders in **Today proper**, below the day's daytime rows and ABOVE the
10
+ * "This Evening" section header, exactly like any other arrived member
11
+ * ([STEV1](../../docs/lab/stev1-stale-evening.md) cell 1).
12
+ *
13
+ * Every consumer of the evening flag therefore has to apply the same gate, and
14
+ * they must all apply the SAME one: the read views, the reorder scopes' member
15
+ * census, the bounce's concurrent-edit re-check, and the move planner's axis
16
+ * choice. Four independent spellings is what left a stale evening item refused by
17
+ * BOTH reorder scopes (#657) — `--in today` called it an evening-bucket item and
18
+ * `--in evening` called it stale. This module is the single spelling.
19
+ */
20
+ /**
21
+ * The Today/Evening placement of a row on the SCHEDULED arm, under `packedToday`
22
+ * (the device-local day, encoded — never a UTC date; see
23
+ * [timezones](../../docs/reference/timezones.md)).
24
+ *
25
+ * - An Inbox row (`start=0`) is never a scheduled Today member.
26
+ * - An undated or strictly-future row is not a member either.
27
+ * - An ARRIVED row (`startDate <= today`, `start` 1 or 2) IS a Today member — an
28
+ * overdue day and an arrived someday-scheduled row included.
29
+ * - It is in **This Evening** only while its evening flag is LIVE: `startBucket=1`
30
+ * with a `startDate` of EXACTLY today. Evening membership expires daily, so a
31
+ * past-dated bucket-1 row is `"today"`.
32
+ *
33
+ * Arrivedness is judged on the DATE alone, never on the start state: an arrived
34
+ * someday-scheduled row (`start=2`, `startDate <= today`) is a Today member and
35
+ * buckets today/evening like any other, matching how `deriveStage` reports it as
36
+ * `anytime` carrying the Today marker (#325).
37
+ *
38
+ * The DEADLINE arm of Today membership (an undated row pulled in by a due or
39
+ * overdue deadline) is not expressible from these three columns and is layered on
40
+ * by the reader (`mappers.todayMarkers`); it is never an evening member.
41
+ */
42
+ export function todayPlacement(row, packedToday) {
43
+ if (row.start !== 1 && row.start !== 2)
44
+ return null;
45
+ if (row.startDate === null || row.startDate > packedToday)
46
+ return null;
47
+ return row.startBucket === 1 && row.startDate === packedToday ? "evening" : "today";
48
+ }
49
+ /**
50
+ * Whether a row's evening flag has gone STALE: the `startBucket=1` byte is still
51
+ * set, but the day it was set for has passed, so the app renders the row in Today
52
+ * proper. The reorder scopes use this to tell a stale movee (accepted by the
53
+ * `today` scope) from a live evening one (refused there, O03), and to point a
54
+ * stale movee's `evening`-scope refusal at the scope that does take it.
55
+ */
56
+ export function isStaleEvening(row, packedToday) {
57
+ return row.startBucket === 1 && todayPlacement(row, packedToday) === "today";
58
+ }
59
+ //# sourceMappingURL=today-placement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"today-placement.js","sourceRoot":"","sources":["../../src/model/today-placement.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAmBH;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,cAAc,CAAC,GAAsB,EAAE,WAAmB;IACxE,IAAI,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,GAAG,CAAC,KAAK,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACpD,IAAI,GAAG,CAAC,SAAS,KAAK,IAAI,IAAI,GAAG,CAAC,SAAS,GAAG,WAAW;QAAE,OAAO,IAAI,CAAC;IACvE,OAAO,GAAG,CAAC,WAAW,KAAK,CAAC,IAAI,GAAG,CAAC,SAAS,KAAK,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;AACtF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,GAAsB,EAAE,WAAmB;IACxE,OAAO,GAAG,CAAC,WAAW,KAAK,CAAC,IAAI,cAAc,CAAC,GAAG,EAAE,WAAW,CAAC,KAAK,OAAO,CAAC;AAC/E,CAAC"}
@@ -790,7 +790,9 @@ const projectSetTags = {
790
790
  };
791
791
  const projectMove = {
792
792
  op: "project.move",
793
- hazards: ["H-UNKNOWN-DESTINATION", "H-REPEAT-SCHEDULE"],
793
+ // No H-REPEAT-SCHEDULE: a repeating project's AREA is independently mutable
794
+ // (TMOV1 P1/P2), and a project has no built-in-list destination to fence.
795
+ hazards: ["H-UNKNOWN-DESTINATION"],
794
796
  preRead(db, params) {
795
797
  if ((params.noArea === true) === containerGiven(params.area)) {
796
798
  throw new RangeError("project.move needs exactly one of area / --no-area");