things-api 0.17.0 → 0.19.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 (277) hide show
  1. package/README.md +16 -9
  2. package/deputy/AppIcon.icns +0 -0
  3. package/deputy/VERSION +1 -0
  4. package/deputy/helpers-Info.plist +27 -0
  5. package/deputy/prebuilt/Things API Helper.app/Contents/CodeResources +0 -0
  6. package/deputy/prebuilt/Things API Helper.app/Contents/Helpers/things-reader.app/Contents/Info.plist +22 -0
  7. package/deputy/prebuilt/Things API Helper.app/Contents/Helpers/things-reader.app/Contents/MacOS/things-reader +0 -0
  8. package/deputy/prebuilt/Things API Helper.app/Contents/Helpers/things-reader.app/Contents/Resources/AppIcon.icns +0 -0
  9. package/deputy/prebuilt/Things API Helper.app/Contents/Helpers/things-reader.app/Contents/_CodeSignature/CodeResources +128 -0
  10. package/deputy/prebuilt/Things API Helper.app/Contents/Info.plist +27 -0
  11. package/deputy/prebuilt/Things API Helper.app/Contents/MacOS/things-deputy +0 -0
  12. package/deputy/prebuilt/Things API Helper.app/Contents/Resources/AppIcon.icns +0 -0
  13. package/deputy/prebuilt/Things API Helper.app/Contents/_CodeSignature/CodeResources +137 -0
  14. package/deputy/reader/Info.plist +22 -0
  15. package/deputy/reader/entitlements.plist +45 -0
  16. package/deputy/reader/main.swift +580 -0
  17. package/deputy/src/main.swift +133 -0
  18. package/deputy/src/osascript.swift +102 -0
  19. package/deputy/src/server.swift +373 -0
  20. package/deputy/src/sqlite.swift +121 -0
  21. package/deputy/src/tcc.swift +58 -0
  22. package/dist/audit/schema.d.ts +13 -1
  23. package/dist/audit/schema.js.map +1 -1
  24. package/dist/capability.d.ts +160 -0
  25. package/dist/capability.js +416 -0
  26. package/dist/capability.js.map +1 -0
  27. package/dist/cli/commands/doctor.js +181 -2
  28. package/dist/cli/commands/doctor.js.map +1 -1
  29. package/dist/cli/commands/helpers.d.ts +17 -0
  30. package/dist/cli/commands/helpers.js +275 -0
  31. package/dist/cli/commands/helpers.js.map +1 -0
  32. package/dist/cli/commands/op-result.d.ts +15 -0
  33. package/dist/cli/commands/op-result.js +45 -0
  34. package/dist/cli/commands/op-result.js.map +1 -0
  35. package/dist/cli/commands/reads.js +47 -1
  36. package/dist/cli/commands/reads.js.map +1 -1
  37. package/dist/cli/commands/setup.d.ts +9 -0
  38. package/dist/cli/commands/setup.js +63 -83
  39. package/dist/cli/commands/setup.js.map +1 -1
  40. package/dist/cli/commands/writes.d.ts +1 -1
  41. package/dist/cli/commands/writes.js +262 -109
  42. package/dist/cli/commands/writes.js.map +1 -1
  43. package/dist/cli/dry-run.d.ts +1 -1
  44. package/dist/cli/dry-run.js +1 -1
  45. package/dist/cli/glyphs.d.ts +23 -4
  46. package/dist/cli/glyphs.js +46 -19
  47. package/dist/cli/glyphs.js.map +1 -1
  48. package/dist/cli/help.d.ts +1 -1
  49. package/dist/cli/help.js +53 -27
  50. package/dist/cli/help.js.map +1 -1
  51. package/dist/cli/helpers-check.d.ts +10 -0
  52. package/dist/cli/helpers-check.js +59 -0
  53. package/dist/cli/helpers-check.js.map +1 -0
  54. package/dist/cli/main.js +22 -1
  55. package/dist/cli/main.js.map +1 -1
  56. package/dist/cli/period.d.ts +3 -1
  57. package/dist/cli/period.js +1 -1
  58. package/dist/cli/period.js.map +1 -1
  59. package/dist/cli/read-driver.js +26 -1
  60. package/dist/cli/read-driver.js.map +1 -1
  61. package/dist/cli/render.d.ts +31 -4
  62. package/dist/cli/render.js +127 -15
  63. package/dist/cli/render.js.map +1 -1
  64. package/dist/client.d.ts +22 -2
  65. package/dist/client.js +52 -15
  66. package/dist/client.js.map +1 -1
  67. package/dist/config.d.ts +31 -0
  68. package/dist/config.js +9 -0
  69. package/dist/config.js.map +1 -1
  70. package/dist/contracts.d.ts +6 -2
  71. package/dist/contracts.js +1 -1
  72. package/dist/contracts.js.map +1 -1
  73. package/dist/db/baselines/db-v26.js +8 -4
  74. package/dist/db/baselines/db-v26.js.map +1 -1
  75. package/dist/db/baselines/db-v27.d.ts +42 -0
  76. package/dist/db/baselines/db-v27.js +47 -0
  77. package/dist/db/baselines/db-v27.js.map +1 -0
  78. package/dist/db/baselines/index.js +2 -1
  79. package/dist/db/baselines/index.js.map +1 -1
  80. package/dist/db/locate.d.ts +4 -1
  81. package/dist/db/locate.js +3 -1
  82. package/dist/db/locate.js.map +1 -1
  83. package/dist/db/schema.d.ts +1 -1
  84. package/dist/db/schema.js +9 -0
  85. package/dist/db/schema.js.map +1 -1
  86. package/dist/deputy/bridge-worker.d.ts +1 -0
  87. package/dist/deputy/bridge-worker.js +79 -0
  88. package/dist/deputy/bridge-worker.js.map +1 -0
  89. package/dist/deputy/bridge.d.ts +14 -0
  90. package/dist/deputy/bridge.js +70 -0
  91. package/dist/deputy/bridge.js.map +1 -0
  92. package/dist/deputy/client.d.ts +19 -0
  93. package/dist/deputy/client.js +104 -0
  94. package/dist/deputy/client.js.map +1 -0
  95. package/dist/deputy/db-facade.d.ts +18 -0
  96. package/dist/deputy/db-facade.js +71 -0
  97. package/dist/deputy/db-facade.js.map +1 -0
  98. package/dist/deputy/files.d.ts +1 -0
  99. package/dist/deputy/files.js +16 -0
  100. package/dist/deputy/files.js.map +1 -0
  101. package/dist/deputy/install.d.ts +319 -0
  102. package/dist/deputy/install.js +1239 -0
  103. package/dist/deputy/install.js.map +1 -0
  104. package/dist/deputy/notice.d.ts +6 -0
  105. package/dist/deputy/notice.js +28 -0
  106. package/dist/deputy/notice.js.map +1 -0
  107. package/dist/deputy/notices.d.ts +31 -0
  108. package/dist/deputy/notices.js +94 -0
  109. package/dist/deputy/notices.js.map +1 -0
  110. package/dist/deputy/osa.d.ts +21 -0
  111. package/dist/deputy/osa.js +72 -0
  112. package/dist/deputy/osa.js.map +1 -0
  113. package/dist/deputy/protocol.d.ts +140 -0
  114. package/dist/deputy/protocol.js +143 -0
  115. package/dist/deputy/protocol.js.map +1 -0
  116. package/dist/deputy/routing.d.ts +84 -0
  117. package/dist/deputy/routing.js +422 -0
  118. package/dist/deputy/routing.js.map +1 -0
  119. package/dist/deputy/shortcuts-exec.d.ts +10 -0
  120. package/dist/deputy/shortcuts-exec.js +50 -0
  121. package/dist/deputy/shortcuts-exec.js.map +1 -0
  122. package/dist/diagnose.d.ts +57 -2
  123. package/dist/diagnose.js +105 -3
  124. package/dist/diagnose.js.map +1 -1
  125. package/dist/direct-setup.d.ts +78 -0
  126. package/dist/direct-setup.js +484 -0
  127. package/dist/direct-setup.js.map +1 -0
  128. package/dist/host-access.d.ts +63 -0
  129. package/dist/host-access.js +165 -0
  130. package/dist/host-access.js.map +1 -0
  131. package/dist/index.d.ts +31 -5
  132. package/dist/index.js +23 -1
  133. package/dist/index.js.map +1 -1
  134. package/dist/mcp/server.d.ts +27 -1
  135. package/dist/mcp/server.js +300 -97
  136. package/dist/mcp/server.js.map +1 -1
  137. package/dist/model/mappers.d.ts +12 -3
  138. package/dist/model/mappers.js +6 -1
  139. package/dist/model/mappers.js.map +1 -1
  140. package/dist/model/recurrence.d.ts +5 -1
  141. package/dist/model/recurrence.js +19 -1
  142. package/dist/model/recurrence.js.map +1 -1
  143. package/dist/model/template-projection.d.ts +26 -0
  144. package/dist/model/template-projection.js +113 -0
  145. package/dist/model/template-projection.js.map +1 -0
  146. package/dist/op-result.d.ts +55 -0
  147. package/dist/op-result.js +161 -0
  148. package/dist/op-result.js.map +1 -0
  149. package/dist/read/detail.js +7 -1
  150. package/dist/read/detail.js.map +1 -1
  151. package/dist/read/filter-contract.d.ts +1 -1
  152. package/dist/read/filter-contract.js +4 -0
  153. package/dist/read/filter-contract.js.map +1 -1
  154. package/dist/read/queries.js +8 -1
  155. package/dist/read/queries.js.map +1 -1
  156. package/dist/read/shape.js +4 -0
  157. package/dist/read/shape.js.map +1 -1
  158. package/dist/read/views.d.ts +35 -4
  159. package/dist/read/views.js +120 -18
  160. package/dist/read/views.js.map +1 -1
  161. package/dist/session-grant.d.ts +48 -0
  162. package/dist/session-grant.js +170 -0
  163. package/dist/session-grant.js.map +1 -0
  164. package/dist/surface-copy.d.ts +8 -0
  165. package/dist/surface-copy.js +8 -0
  166. package/dist/surface-copy.js.map +1 -1
  167. package/dist/sync-health.js +6 -2
  168. package/dist/sync-health.js.map +1 -1
  169. package/dist/wizard.d.ts +58 -0
  170. package/dist/wizard.js +167 -0
  171. package/dist/wizard.js.map +1 -0
  172. package/dist/write/accessibility-probe.js +4 -2
  173. package/dist/write/accessibility-probe.js.map +1 -1
  174. package/dist/write/automation-probe.js +5 -1
  175. package/dist/write/automation-probe.js.map +1 -1
  176. package/dist/write/availability.d.ts +1 -1
  177. package/dist/write/availability.js +10 -6
  178. package/dist/write/availability.js.map +1 -1
  179. package/dist/write/batch.d.ts +20 -0
  180. package/dist/write/batch.js +94 -15
  181. package/dist/write/batch.js.map +1 -1
  182. package/dist/write/capabilities.d.ts +9 -0
  183. package/dist/write/capabilities.js +2 -0
  184. package/dist/write/capabilities.js.map +1 -1
  185. package/dist/write/clear-reminder.js +1 -1
  186. package/dist/write/clear-reminder.js.map +1 -1
  187. package/dist/write/commands.d.ts +12 -1
  188. package/dist/write/commands.js +170 -237
  189. package/dist/write/commands.js.map +1 -1
  190. package/dist/write/experimental.d.ts +19 -0
  191. package/dist/write/experimental.js +50 -0
  192. package/dist/write/experimental.js.map +1 -1
  193. package/dist/write/failure-hints.d.ts +3 -1
  194. package/dist/write/failure-hints.js.map +1 -1
  195. package/dist/write/guards.js +19 -2
  196. package/dist/write/guards.js.map +1 -1
  197. package/dist/write/lock.d.ts +16 -13
  198. package/dist/write/lock.js +55 -0
  199. package/dist/write/lock.js.map +1 -1
  200. package/dist/write/make-repeating-project.js +9 -13
  201. package/dist/write/make-repeating-project.js.map +1 -1
  202. package/dist/write/move.js +14 -6
  203. package/dist/write/move.js.map +1 -1
  204. package/dist/write/operations.d.ts +64 -25
  205. package/dist/write/operations.js +7 -0
  206. package/dist/write/operations.js.map +1 -1
  207. package/dist/write/opid.d.ts +14 -0
  208. package/dist/write/opid.js +22 -0
  209. package/dist/write/opid.js.map +1 -1
  210. package/dist/write/param-schema.d.ts +124 -0
  211. package/dist/write/param-schema.js +747 -0
  212. package/dist/write/param-schema.js.map +1 -0
  213. package/dist/write/pipeline.d.ts +78 -2
  214. package/dist/write/pipeline.js +249 -4
  215. package/dist/write/pipeline.js.map +1 -1
  216. package/dist/write/pre-state.d.ts +8 -0
  217. package/dist/write/pre-state.js +62 -17
  218. package/dist/write/pre-state.js.map +1 -1
  219. package/dist/write/promote-clone.js +635 -367
  220. package/dist/write/promote-clone.js.map +1 -1
  221. package/dist/write/reorder.js +95 -29
  222. package/dist/write/reorder.js.map +1 -1
  223. package/dist/write/repeat-anchor.d.ts +30 -0
  224. package/dist/write/repeat-anchor.js +166 -1
  225. package/dist/write/repeat-anchor.js.map +1 -1
  226. package/dist/write/repeat-rule.d.ts +28 -1
  227. package/dist/write/repeat-rule.js +64 -4
  228. package/dist/write/repeat-rule.js.map +1 -1
  229. package/dist/write/resolution-timestamps.d.ts +11 -0
  230. package/dist/write/resolution-timestamps.js +83 -38
  231. package/dist/write/resolution-timestamps.js.map +1 -1
  232. package/dist/write/reversibility.js +4 -0
  233. package/dist/write/reversibility.js.map +1 -1
  234. package/dist/write/template-mutation.d.ts +137 -0
  235. package/dist/write/template-mutation.js +451 -0
  236. package/dist/write/template-mutation.js.map +1 -0
  237. package/dist/write/undo.js +10 -20
  238. package/dist/write/undo.js.map +1 -1
  239. package/dist/write/update-fields.d.ts +151 -0
  240. package/dist/write/update-fields.js +427 -0
  241. package/dist/write/update-fields.js.map +1 -0
  242. package/dist/write/vectors/applescript.js +10 -16
  243. package/dist/write/vectors/applescript.js.map +1 -1
  244. package/dist/write/vectors/registry.d.ts +1 -1
  245. package/dist/write/vectors/registry.js +10 -2
  246. package/dist/write/vectors/registry.js.map +1 -1
  247. package/dist/write/vectors/session-reachability.d.ts +55 -0
  248. package/dist/write/vectors/session-reachability.js +56 -8
  249. package/dist/write/vectors/session-reachability.js.map +1 -1
  250. package/dist/write/vectors/shortcuts.js +7 -16
  251. package/dist/write/vectors/shortcuts.js.map +1 -1
  252. package/dist/write/vectors/simulator.d.ts +16 -1
  253. package/dist/write/vectors/simulator.js +68 -12
  254. package/dist/write/vectors/simulator.js.map +1 -1
  255. package/dist/write/vectors/types.d.ts +124 -1
  256. package/dist/write/vectors/ui-recipes.d.ts +19 -0
  257. package/dist/write/vectors/ui-recipes.js +158 -38
  258. package/dist/write/vectors/ui-recipes.js.map +1 -1
  259. package/dist/write/vectors/ui.d.ts +89 -0
  260. package/dist/write/vectors/ui.js +504 -49
  261. package/dist/write/vectors/ui.js.map +1 -1
  262. package/dist/write/verify/delta.d.ts +21 -0
  263. package/dist/write/verify/delta.js.map +1 -1
  264. package/dist/write/verify/poller.d.ts +13 -0
  265. package/dist/write/verify/poller.js +38 -0
  266. package/dist/write/verify/poller.js.map +1 -1
  267. package/package.json +9 -1
  268. package/schema/envelope.schema.json +5 -3
  269. package/scripts/build-helpers.sh +109 -0
  270. package/scripts/deputy-cert-setup.sh +60 -0
  271. package/skills/things-cli/SKILL.md +12 -5
  272. package/skills/things-cli/references/contracts.md +1 -0
  273. package/skills/things-cli/references/data-model.md +3 -0
  274. package/skills/things-cli/references/errors.md +5 -1
  275. package/skills/things-cli/references/gui.md +1 -0
  276. package/skills/things-cli/references/repeating.md +75 -0
  277. package/skills/things-cli/references/tag-cleanup.md +64 -0
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Template-mutation composites — "Create Next Copy, then mutate the instance"
3
+ * (design of record: docs/lab/cnc1-template-mutations.md; ruling 2026-08-24).
4
+ *
5
+ * A repeating template refuses every schedule/status write we ship, and the
6
+ * app's own Make Exception chooser is not on the automation path. CNC1 measured
7
+ * the alternative and it is exact: `Items ▸ Repeat ▸ Create Next Copy` followed
8
+ * by an ordinary write to the row it mints reproduces Make Exception FIELD FOR
9
+ * FIELD on the template (weekly against REPX3 §1.2, daily against §2.1; the
10
+ * vacated slot then stays silent when the clock reaches it, against a live
11
+ * control that spawns normally). The composite differs from the chooser by one
12
+ * column on one row — the minted instance's modification stamp, which the
13
+ * chooser leaves unset — and that difference is the winning side of Things
14
+ * Cloud's merge arbitration (SYNCX1), so it is the safe direction.
15
+ *
16
+ * Two composites live here:
17
+ *
18
+ * - {@link runTemplateStatusWrite} — `complete`/`cancel` aimed at a series.
19
+ * UNFLAGGED, because there is exactly one sane reading of "check off this
20
+ * repeating to-do". If the series already has an OPEN materialized
21
+ * occurrence, that IS the current one and it is resolved directly (no
22
+ * mint); otherwise the pending occurrence is materialized first and
23
+ * resolved. Either way the template is left byte-unchanged and the series
24
+ * continues on schedule (CNC1 §6, measured for `cancel` as well as
25
+ * `complete`).
26
+ *
27
+ * - {@link runTemplateExceptionWrite} — `update --exception` aimed at a
28
+ * series: move/re-deadline/re-remind ONLY the next occurrence. Always mints,
29
+ * because the exception semantics belong to the PENDING occurrence — the one
30
+ * the rule has not spawned yet. (Re-dating an already-materialized
31
+ * occurrence is an ordinary update on that row and consumes no slot, so the
32
+ * rule would still spawn its own copy — REPX1 §3.2. Callers who want that
33
+ * can address the occurrence directly.)
34
+ *
35
+ * Three refusals, each measured, are enforced before anything is driven:
36
+ *
37
+ * 1. a target date that is a live slot of the same rule DOUBLE-BOOKS that day
38
+ * (CNC1 §2, inheriting oddities §17 whole);
39
+ * 2. a series with NO CURSOR has no pending occurrence to materialize, and
40
+ * `Create Next Copy` duplicates the current one onto the same day instead
41
+ * (CNC1 §5, CNCAC1 §6/§8, oddities §18);
42
+ * 3. repeating PROJECTS are out of scope: the menu that carries the command
43
+ * does not exist for a project selection (CNC1 §8).
44
+ *
45
+ * Refusal 2 used to be keyed on the rule KIND — "after-completion" — and that
46
+ * was fail-closed guesswork that fired on the wrong state. CNCAC1 measured the
47
+ * shape it was actually hitting: an after-completion series ANCHORS on its
48
+ * occurrence being resolved and DERIVES a real cursor from that anchor, so a
49
+ * series with a completed history renders a projection in Upcoming, the GUI
50
+ * checks that projection off, and `Create Next Copy` materializes it correctly
51
+ * with no duplicate — byte-equivalent to the GUI gesture modulo the minted row's
52
+ * modification stamp. The duplicate belongs to the CURSOR-LESS case alone (a
53
+ * never-resolved series, or a paused one), which is what this now refuses.
54
+ *
55
+ * Reversibility is HALF and is disclosed at op time: `things undo` restores the
56
+ * occurrence's own change perfectly, and can neither remove the materialized
57
+ * occurrence nor rewind the series (CNC1 §7).
58
+ *
59
+ * Two contract facts hold for BOTH composites (ruling 2026-08-25):
60
+ *
61
+ * - The result NAMES THE OCCURRENCE. Every success carries an
62
+ * {@link OccurrenceResolution}: the template the caller aimed at, the
63
+ * occurrence that was actually written, and whether that occurrence was
64
+ * minted for this call or already existed. The caller never has to infer
65
+ * which row moved — the same courtesy `add-repeating` does with its
66
+ * template/instance pair.
67
+ *
68
+ * - The composite is ONE op for idempotency. It records a single summary
69
+ * record (the legs stay legs, and the caller's `opId` rides the summary
70
+ * alone), so a caller that retries after an ambiguous failure — a killed
71
+ * process, a timed-out agent — replays the recorded result instead of
72
+ * minting a SECOND occurrence and advancing the series a second time. Every
73
+ * re-run without a key is a genuinely new action, which is exactly the
74
+ * add-repeating hazard class: pass `--op-id` on a retry.
75
+ */
76
+ import { type IsoDate } from "../model/dates.ts";
77
+ import type { RepeatRule } from "../model/recurrence.ts";
78
+ import type { UpdateFields } from "./operations.ts";
79
+ import { type MutationResult, type WriteDeps, type WriteOptions } from "./pipeline.ts";
80
+ declare const PROJECT_REFUSAL = "this is a repeating project, and only repeating to-dos can have a single occurrence changed";
81
+ declare const PROJECT_REMEDIATION: string;
82
+ /** What the composite learned about the series before it drove anything. */
83
+ interface SeriesState {
84
+ templateUuid: string;
85
+ title: string;
86
+ /** The pending occurrence's date — the slot a mint would consume. */
87
+ cursor: IsoDate | null;
88
+ rule: RepeatRule | null;
89
+ deadlined: boolean;
90
+ afterCompletion: boolean;
91
+ /** The series is paused, which is WHY it has no cursor — a different remedy. */
92
+ paused: boolean;
93
+ /** An already-materialized OPEN occurrence of this series, if there is one. */
94
+ openInstance: {
95
+ uuid: string;
96
+ startDate: IsoDate | null;
97
+ } | null;
98
+ }
99
+ /**
100
+ * Read everything the composite decides on, in one pass. Returns null when the
101
+ * target is not a repeating to-do template, which the caller has already
102
+ * established but which keeps this total.
103
+ */
104
+ export declare function readSeriesState(deps: WriteDeps, uuid: string): SeriesState | null;
105
+ /**
106
+ * The dates this rule will still produce ON ITS OWN after the pending
107
+ * occurrence has been materialized — i.e. every slot from the one AFTER the
108
+ * cursor up to and including `until`. Landing an occurrence on one of these
109
+ * leaves that day holding two copies once the clock reaches it (CNC1 §2), which
110
+ * is the whole reason this list exists.
111
+ *
112
+ * Empty when the rule is undecodable or has no calendar: nothing can be proven
113
+ * about a rule we cannot read, and the caller refuses rather than guessing.
114
+ */
115
+ export declare function liveSlotsAfterMint(state: SeriesState, until: IsoDate): IsoDate[];
116
+ /**
117
+ * `complete`/`cancel` aimed at a repeating to-do. Resolves the series' CURRENT
118
+ * occurrence: the open materialized one when it exists, otherwise the pending
119
+ * one, materialized first. The template itself is never written — CNC1 §6
120
+ * measured both status writes leaving it byte-unchanged, with the series
121
+ * continuing at its next date and exactly one occurrence per day.
122
+ */
123
+ export declare function runTemplateStatusWrite(deps: WriteDeps, op: "todo.complete" | "todo.cancel", uuid: string,
124
+ /**
125
+ * The status write itself, applied to ONE ordinary occurrence. Injected
126
+ * rather than imported so the caller keeps ownership of its own vocabulary —
127
+ * `--completed-at` backdating, the children policy — and so this module does
128
+ * not have to import the resolution orchestrator that calls it.
129
+ */
130
+ runStatusLeg: (occurrenceUuid: string, legOptions: WriteOptions) => Promise<MutationResult>, options?: WriteOptions): Promise<MutationResult>;
131
+ /**
132
+ * `update --exception` aimed at a repeating to-do: change ONLY the next
133
+ * occurrence. Materializes the pending occurrence and applies the patch to it,
134
+ * which is what the app's own "make a one-time exception" does.
135
+ */
136
+ export declare function runTemplateExceptionWrite(deps: WriteDeps, uuid: string, patch: UpdateFields & Record<string, unknown>, options?: WriteOptions): Promise<MutationResult>;
137
+ export { PROJECT_REFUSAL, PROJECT_REMEDIATION };
@@ -0,0 +1,451 @@
1
+ /**
2
+ * Template-mutation composites — "Create Next Copy, then mutate the instance"
3
+ * (design of record: docs/lab/cnc1-template-mutations.md; ruling 2026-08-24).
4
+ *
5
+ * A repeating template refuses every schedule/status write we ship, and the
6
+ * app's own Make Exception chooser is not on the automation path. CNC1 measured
7
+ * the alternative and it is exact: `Items ▸ Repeat ▸ Create Next Copy` followed
8
+ * by an ordinary write to the row it mints reproduces Make Exception FIELD FOR
9
+ * FIELD on the template (weekly against REPX3 §1.2, daily against §2.1; the
10
+ * vacated slot then stays silent when the clock reaches it, against a live
11
+ * control that spawns normally). The composite differs from the chooser by one
12
+ * column on one row — the minted instance's modification stamp, which the
13
+ * chooser leaves unset — and that difference is the winning side of Things
14
+ * Cloud's merge arbitration (SYNCX1), so it is the safe direction.
15
+ *
16
+ * Two composites live here:
17
+ *
18
+ * - {@link runTemplateStatusWrite} — `complete`/`cancel` aimed at a series.
19
+ * UNFLAGGED, because there is exactly one sane reading of "check off this
20
+ * repeating to-do". If the series already has an OPEN materialized
21
+ * occurrence, that IS the current one and it is resolved directly (no
22
+ * mint); otherwise the pending occurrence is materialized first and
23
+ * resolved. Either way the template is left byte-unchanged and the series
24
+ * continues on schedule (CNC1 §6, measured for `cancel` as well as
25
+ * `complete`).
26
+ *
27
+ * - {@link runTemplateExceptionWrite} — `update --exception` aimed at a
28
+ * series: move/re-deadline/re-remind ONLY the next occurrence. Always mints,
29
+ * because the exception semantics belong to the PENDING occurrence — the one
30
+ * the rule has not spawned yet. (Re-dating an already-materialized
31
+ * occurrence is an ordinary update on that row and consumes no slot, so the
32
+ * rule would still spawn its own copy — REPX1 §3.2. Callers who want that
33
+ * can address the occurrence directly.)
34
+ *
35
+ * Three refusals, each measured, are enforced before anything is driven:
36
+ *
37
+ * 1. a target date that is a live slot of the same rule DOUBLE-BOOKS that day
38
+ * (CNC1 §2, inheriting oddities §17 whole);
39
+ * 2. a series with NO CURSOR has no pending occurrence to materialize, and
40
+ * `Create Next Copy` duplicates the current one onto the same day instead
41
+ * (CNC1 §5, CNCAC1 §6/§8, oddities §18);
42
+ * 3. repeating PROJECTS are out of scope: the menu that carries the command
43
+ * does not exist for a project selection (CNC1 §8).
44
+ *
45
+ * Refusal 2 used to be keyed on the rule KIND — "after-completion" — and that
46
+ * was fail-closed guesswork that fired on the wrong state. CNCAC1 measured the
47
+ * shape it was actually hitting: an after-completion series ANCHORS on its
48
+ * occurrence being resolved and DERIVES a real cursor from that anchor, so a
49
+ * series with a completed history renders a projection in Upcoming, the GUI
50
+ * checks that projection off, and `Create Next Copy` materializes it correctly
51
+ * with no duplicate — byte-equivalent to the GUI gesture modulo the minted row's
52
+ * modification stamp. The duplicate belongs to the CURSOR-LESS case alone (a
53
+ * never-resolved series, or a paused one), which is what this now refuses.
54
+ *
55
+ * Reversibility is HALF and is disclosed at op time: `things undo` restores the
56
+ * occurrence's own change perfectly, and can neither remove the materialized
57
+ * occurrence nor rewind the series (CNC1 §7).
58
+ *
59
+ * Two contract facts hold for BOTH composites (ruling 2026-08-25):
60
+ *
61
+ * - The result NAMES THE OCCURRENCE. Every success carries an
62
+ * {@link OccurrenceResolution}: the template the caller aimed at, the
63
+ * occurrence that was actually written, and whether that occurrence was
64
+ * minted for this call or already existed. The caller never has to infer
65
+ * which row moved — the same courtesy `add-repeating` does with its
66
+ * template/instance pair.
67
+ *
68
+ * - The composite is ONE op for idempotency. It records a single summary
69
+ * record (the legs stay legs, and the caller's `opId` rides the summary
70
+ * alone), so a caller that retries after an ambiguous failure — a killed
71
+ * process, a timed-out agent — replays the recorded result instead of
72
+ * minting a SECOND occurrence and advancing the series a second time. Every
73
+ * re-run without a key is a genuinely new action, which is exactly the
74
+ * add-repeating hazard class: pass `--op-id` on a retry.
75
+ */
76
+ import { addDaysIso, decodePackedDate, localToday } from "../model/dates.js";
77
+ import { projectOccurrences } from "../model/occurrences.js";
78
+ import { byUuid } from "../read/detail.js";
79
+ import { replayIfApplied } from "./opid.js";
80
+ import { appendCompositeSummary, runComposite, runMutation, } from "./pipeline.js";
81
+ /** How far ahead the collision check will look for a live slot. */
82
+ const SLOT_LOOKAHEAD = 400;
83
+ const IRREVERSIBLE_NOTE = "`things undo` restores this occurrence's own change; it cannot remove the occurrence that was " +
84
+ "created for it, and the series has already moved on to its following date";
85
+ const PROJECT_REFUSAL = "this is a repeating project, and only repeating to-dos can have a single occurrence changed";
86
+ const PROJECT_REMEDIATION = "change the whole series with `things project reschedule-repeat <ref>`, or change one of its " +
87
+ "to-dos directly";
88
+ /**
89
+ * The precondition, stated as what it actually is. A composite can only work on
90
+ * an occurrence the series has NOT spawned yet, and the app tells us whether
91
+ * there is one: `rt1_nextInstanceStartDate`. When it is null there is no next
92
+ * date to bring forward, and `Create Next Copy` does not refuse — it DUPLICATES
93
+ * the current occurrence onto the same day (CNC1 §5 / CNCAC1 §6, oddities §18).
94
+ *
95
+ * This replaces a rule-KIND refusal that fired on the wrong state. It read "an
96
+ * after-completion series has no upcoming occurrence until the current one is
97
+ * done" — but CNCAC1 measured that an after-completion series acquires a real
98
+ * cursor the moment its occurrence is resolved (completed, canceled, OR
99
+ * trashed), which is precisely when the old branch fired: it refused the one
100
+ * shape whose projection the app renders in Upcoming and happily checks off.
101
+ *
102
+ * With that corrected, the only state that reaches this refusal is a PAUSED
103
+ * series whose occurrence is already resolved — and there the refusal earns its
104
+ * keep for a second measured reason. CNC on a paused series does not duplicate;
105
+ * it quietly materializes the occurrence the pause was suppressing, from the
106
+ * stale anchor, and clears that anchor while leaving the paused flag set
107
+ * (CNCAC1 §8). Producing an occurrence from a series the user deliberately
108
+ * paused is not a reading of "check this off" worth guessing at, so the refusal
109
+ * names `resume-repeat` instead.
110
+ */
111
+ const NO_PENDING_REFUSAL = "this repeating to-do has no upcoming occurrence to work on — its schedule names no next date, " +
112
+ "so there is nothing to bring forward";
113
+ function blocked(op, detail, remediation) {
114
+ return { kind: "blocked", op, reason: "environment", detail, remediation };
115
+ }
116
+ /**
117
+ * Read everything the composite decides on, in one pass. Returns null when the
118
+ * target is not a repeating to-do template, which the caller has already
119
+ * established but which keeps this total.
120
+ */
121
+ export function readSeriesState(deps, uuid) {
122
+ const target = byUuid(deps.db, uuid);
123
+ if (target === null || target.type === "heading" || !target.repeating.isTemplate)
124
+ return null;
125
+ const rule = target.repeating.rule ?? null;
126
+ const rows = deps.db
127
+ .prepare("SELECT uuid, startDate FROM TMTask WHERE rt1_repeatingTemplate = ? AND trashed = 0 " +
128
+ "AND status = 0 ORDER BY startDate, creationDate")
129
+ .all(uuid);
130
+ const first = rows[0];
131
+ return {
132
+ templateUuid: uuid,
133
+ title: target.title,
134
+ cursor: target.repeating.nextOccurrence ?? null,
135
+ rule,
136
+ deadlined: target.repeating.deadlined === true,
137
+ afterCompletion: rule !== null && rule.type === "after-completion",
138
+ paused: target.repeating.paused === true,
139
+ openInstance: first === undefined
140
+ ? null
141
+ : { uuid: first.uuid, startDate: decodePackedDate(first.startDate) },
142
+ };
143
+ }
144
+ /**
145
+ * The dates this rule will still produce ON ITS OWN after the pending
146
+ * occurrence has been materialized — i.e. every slot from the one AFTER the
147
+ * cursor up to and including `until`. Landing an occurrence on one of these
148
+ * leaves that day holding two copies once the clock reaches it (CNC1 §2), which
149
+ * is the whole reason this list exists.
150
+ *
151
+ * Empty when the rule is undecodable or has no calendar: nothing can be proven
152
+ * about a rule we cannot read, and the caller refuses rather than guessing.
153
+ */
154
+ export function liveSlotsAfterMint(state, until) {
155
+ const { rule, cursor } = state;
156
+ if (rule === null || rule.type !== "fixed" || cursor === null)
157
+ return [];
158
+ if (until <= cursor)
159
+ return [];
160
+ const projected = projectOccurrences(rule, cursor, { count: SLOT_LOOKAHEAD, until }, state.deadlined);
161
+ // The first projection IS the cursor — the slot the mint consumes, not a
162
+ // collision. Everything after it is a slot the rule will still fire.
163
+ return projected.slice(1).map((o) => o.startDate);
164
+ }
165
+ /**
166
+ * Resolve the calendar day a `when` value lands on, or null when it names no
167
+ * single day (`anytime`/`someday` are not dated, so they cannot collide with a
168
+ * slot).
169
+ */
170
+ function whenTargetDay(when, todayIso) {
171
+ if (when === undefined)
172
+ return null;
173
+ if (when === "today" || when === "evening")
174
+ return todayIso;
175
+ if (when === "tomorrow")
176
+ return addDaysIso(todayIso, 1);
177
+ return /^\d{4}-\d{2}-\d{2}$/.test(when) ? when : null;
178
+ }
179
+ /**
180
+ * The refusal for a series with nothing pending, with the remedy that fits WHY
181
+ * it is empty. A paused series is one command away from having a cursor again;
182
+ * anything else is the app's own business.
183
+ */
184
+ function noPendingRefusal(op, state) {
185
+ if (state.paused) {
186
+ return blocked(op, "this repeating to-do is paused, so it has no upcoming occurrence to work on", "resume it first with `things todo resume-repeat <ref>`");
187
+ }
188
+ return blocked(op, NO_PENDING_REFUSAL, "work on one of its occurrences directly");
189
+ }
190
+ /** Human phrasing for "the occurrence dated X" when X may be unknown. */
191
+ function occurrenceLabel(date) {
192
+ return date === null ? "the current occurrence" : `the ${date} occurrence`;
193
+ }
194
+ /** Where the series goes next, read back AFTER the composite has run. */
195
+ function nextOccurrenceAfter(deps, templateUuid) {
196
+ const target = byUuid(deps.db, templateUuid);
197
+ if (target === null || target.type === "heading")
198
+ return null;
199
+ return target.repeating.nextOccurrence ?? null;
200
+ }
201
+ /**
202
+ * Materialize the pending occurrence and hand back its uuid. Split out because
203
+ * both composites need exactly this, including the failure phrasing: a mint
204
+ * that did not land must never be reported as a mutation that did.
205
+ */
206
+ async function mintPendingOccurrence(deps, op, templateUuid, options, txnId) {
207
+ const mint = await runMutation(deps, "todo.create-next-copy", { uuid: templateUuid }, {
208
+ ...legOptions(options, txnId),
209
+ vector: "ui",
210
+ // The GUI-drive ACKNOWLEDGEMENT is made here, on the caller's behalf, and
211
+ // it is the one place in the package that does so. Rationale (ruling
212
+ // 2026-08-24): these verbs are UNFLAGGED — "check off this repeating
213
+ // to-do" and "move only the next occurrence" already name the effect the
214
+ // user asked for, and there is no other way to perform either, so a second
215
+ // flag would be ceremony with no decision behind it. Nothing else is
216
+ // relaxed: Article IV's capability gate still refuses a machine whose
217
+ // helpers have no GUI tier, and the disruption ceiling still refuses
218
+ // unless the caller allowed a change that visibly drives the app — which
219
+ // is the control that keeps this from being a surprise.
220
+ dangerouslyDriveGui: true,
221
+ });
222
+ if (mint.kind !== "ok" || mint.uuid === null) {
223
+ return {
224
+ ok: false,
225
+ result: {
226
+ ...mint,
227
+ op,
228
+ ...("detail" in mint
229
+ ? { detail: `${mint.detail} — no occurrence was created, so nothing was changed` }
230
+ : {}),
231
+ },
232
+ };
233
+ }
234
+ return { ok: true, uuid: mint.uuid };
235
+ }
236
+ function newTxnId(now) {
237
+ return `txn-${now.getTime().toString(36)}-${process.pid.toString(36)}`;
238
+ }
239
+ /**
240
+ * The options a LEG runs under: the caller's, grouped into the composite's txn,
241
+ * with the idempotency key REMOVED. The key identifies the whole composite, and
242
+ * the composite records exactly one record for it (the summary) — leaving it on
243
+ * the legs would put the same key on two or three records and let a resubmission
244
+ * match half a verb.
245
+ */
246
+ function legOptions(options, txnId) {
247
+ const { opId: _opId, ...rest } = options;
248
+ return { ...rest, txn: { id: txnId, role: "leg" } };
249
+ }
250
+ /**
251
+ * Record the composite as ONE summary record and hand back its undo token.
252
+ *
253
+ * This is the record the whole verb is addressed by: `undo` targets it (a leg is
254
+ * never a direct undo target, so before this existed the composite left nothing
255
+ * for `things undo` to reach), and it is the single record the caller's `opId`
256
+ * keys, carrying the occurrence pair so a replay can answer with it.
257
+ *
258
+ * The summary's vector/tier report the composite's MOST disruptive leg: a mint
259
+ * drives the app window, so a minted occurrence is reported as such even though
260
+ * the status/update leg that followed it was an ordinary quiet write.
261
+ */
262
+ function recordComposite(deps, args) {
263
+ return appendCompositeSummary(deps, {
264
+ startedAt: args.startedAt,
265
+ op: args.op,
266
+ uuid: args.occurrence.occurrenceUuid,
267
+ txnId: args.txnId,
268
+ invocation: `${args.op} on repeating series ${args.occurrence.templateUuid}: ` +
269
+ `${args.occurrence.minted ? "create next copy, then " : ""}write ${args.occurrence.occurrenceUuid}`,
270
+ requested: args.requested,
271
+ vector: args.occurrence.minted ? "ui" : args.legResult.vector,
272
+ disruption: args.occurrence.minted ? 3 : args.legResult.tier,
273
+ options: args.options,
274
+ occurrence: args.occurrence,
275
+ });
276
+ }
277
+ // ------------------------------------------------------------ status writes
278
+ /**
279
+ * `complete`/`cancel` aimed at a repeating to-do. Resolves the series' CURRENT
280
+ * occurrence: the open materialized one when it exists, otherwise the pending
281
+ * one, materialized first. The template itself is never written — CNC1 §6
282
+ * measured both status writes leaving it byte-unchanged, with the series
283
+ * continuing at its next date and exactly one occurrence per day.
284
+ */
285
+ export async function runTemplateStatusWrite(deps, op, uuid,
286
+ /**
287
+ * The status write itself, applied to ONE ordinary occurrence. Injected
288
+ * rather than imported so the caller keeps ownership of its own vocabulary —
289
+ * `--completed-at` backdating, the children policy — and so this module does
290
+ * not have to import the resolution orchestrator that calls it.
291
+ */
292
+ runStatusLeg, options = {}) {
293
+ const now = deps.now?.() ?? new Date();
294
+ return runComposite(deps, op, async () => {
295
+ const state = readSeriesState(deps, uuid);
296
+ if (state === null)
297
+ return blocked(op, "this to-do is no longer a repeating series", "retry");
298
+ const txnId = newTxnId(now);
299
+ let targetUuid;
300
+ let occurrenceDate;
301
+ let minted = false;
302
+ if (state.openInstance !== null) {
303
+ targetUuid = state.openInstance.uuid;
304
+ occurrenceDate = state.openInstance.startDate;
305
+ }
306
+ else {
307
+ if (state.cursor === null)
308
+ return noPendingRefusal(op, state);
309
+ const mint = await mintPendingOccurrence(deps, op, state.templateUuid, options, txnId);
310
+ if (!mint.ok)
311
+ return mint.result;
312
+ targetUuid = mint.uuid;
313
+ occurrenceDate = state.cursor;
314
+ minted = true;
315
+ }
316
+ const write = await runStatusLeg(targetUuid, legOptions(options, txnId));
317
+ if (write.kind !== "ok")
318
+ return { ...write, op };
319
+ const occurrence = {
320
+ templateUuid: state.templateUuid,
321
+ occurrenceUuid: targetUuid,
322
+ minted,
323
+ date: occurrenceDate,
324
+ };
325
+ const undoToken = recordComposite(deps, {
326
+ op,
327
+ startedAt: now,
328
+ txnId,
329
+ requested: { uuid: state.templateUuid },
330
+ occurrence,
331
+ legResult: write,
332
+ options,
333
+ });
334
+ const verb = op === "todo.complete" ? "checked off" : "canceled";
335
+ const nextDate = nextOccurrenceAfter(deps, state.templateUuid);
336
+ const disclosure = [
337
+ `${verb} ${occurrenceLabel(occurrenceDate)} of "${state.title}"` +
338
+ (minted ? " (created just now, because the series had no unfinished copy)" : ""),
339
+ nextDate === null
340
+ ? "the series has no further scheduled occurrence"
341
+ : state.afterCompletion
342
+ ? `the next occurrence is ${nextDate} — this series counts from each completion, so ` +
343
+ "resolving it now restarted the interval from today"
344
+ : `the next occurrence is ${nextDate}`,
345
+ ];
346
+ if (minted)
347
+ disclosure.push(IRREVERSIBLE_NOTE);
348
+ return {
349
+ ...write,
350
+ op,
351
+ occurrence,
352
+ undoToken,
353
+ warnings: [...(write.warnings ?? []), ...disclosure],
354
+ };
355
+ });
356
+ }
357
+ // --------------------------------------------------------- exception writes
358
+ /**
359
+ * `update --exception` aimed at a repeating to-do: change ONLY the next
360
+ * occurrence. Materializes the pending occurrence and applies the patch to it,
361
+ * which is what the app's own "make a one-time exception" does.
362
+ */
363
+ export async function runTemplateExceptionWrite(deps, uuid, patch, options = {}) {
364
+ const op = "todo.update";
365
+ const now = deps.now?.() ?? new Date();
366
+ const todayIso = localToday(now, options.zone);
367
+ // Idempotency before the lock, like every refusal: a resubmitted key means the
368
+ // exception already landed, and re-running it would mint a SECOND occurrence
369
+ // (this composite always mints) and consume another of the series' slots.
370
+ const replay = replayIfApplied(deps, options);
371
+ if (replay !== null)
372
+ return replay;
373
+ return runComposite(deps, op, async () => {
374
+ const state = readSeriesState(deps, uuid);
375
+ if (state === null)
376
+ return blocked(op, "this to-do is no longer a repeating series", "retry");
377
+ if (state.cursor === null)
378
+ return noPendingRefusal(op, state);
379
+ // The collision refusal (CNC1 §2). A day the rule will still fire on ends up
380
+ // holding two copies of the series, and nothing in the app reconciles them.
381
+ const targetDay = whenTargetDay(typeof patch["when"] === "string" ? patch["when"] : undefined, todayIso);
382
+ if (targetDay !== null && !state.afterCompletion) {
383
+ // An after-completion series is exempt BY CONSTRUCTION, not by assumption:
384
+ // it has no calendar, so it owns exactly one future date — the cursor this
385
+ // mint is about to consume — and there is no second slot for the moved
386
+ // occurrence to collide with (CNCAC1 §7).
387
+ if (state.rule === null || state.rule.type !== "fixed") {
388
+ return blocked(op, "this series' schedule cannot be read, so there is no way to tell whether " +
389
+ `${targetDay} is a day it already lands on`, "move the occurrence in the Things app, or change the whole series with " +
390
+ "`things todo reschedule-repeat <ref>`");
391
+ }
392
+ if (liveSlotsAfterMint(state, targetDay).includes(targetDay)) {
393
+ return blocked(op, `"${state.title}" already lands on ${targetDay} — moving this occurrence there would ` +
394
+ "leave two copies on that day, and the app does not merge them", "pick a day the series does not already land on, or change the whole series with " +
395
+ "`things todo reschedule-repeat <ref>`");
396
+ }
397
+ }
398
+ const txnId = newTxnId(now);
399
+ const mint = await mintPendingOccurrence(deps, op, state.templateUuid, options, txnId);
400
+ if (!mint.ok)
401
+ return mint.result;
402
+ const write = await runMutation(deps, "todo.update", { uuid: mint.uuid, ...patch }, legOptions(options, txnId));
403
+ if (write.kind !== "ok") {
404
+ return {
405
+ ...write,
406
+ op,
407
+ ...("detail" in write
408
+ ? {
409
+ detail: `${write.detail} — the ${occurrenceLabel(state.cursor)} was created but not ` +
410
+ `changed; it is now a plain to-do you can edit directly (${mint.uuid})`,
411
+ }
412
+ : {}),
413
+ };
414
+ }
415
+ const occurrence = {
416
+ templateUuid: state.templateUuid,
417
+ occurrenceUuid: mint.uuid,
418
+ // An exception ALWAYS mints: the semantics belong to the occurrence the
419
+ // rule has not spawned yet (see the module header).
420
+ minted: true,
421
+ date: state.cursor,
422
+ };
423
+ const undoToken = recordComposite(deps, {
424
+ op,
425
+ startedAt: now,
426
+ txnId,
427
+ requested: { uuid: state.templateUuid, ...patch },
428
+ occurrence,
429
+ legResult: write,
430
+ options,
431
+ });
432
+ const nextDate = nextOccurrenceAfter(deps, state.templateUuid);
433
+ return {
434
+ ...write,
435
+ op,
436
+ occurrence,
437
+ undoToken,
438
+ warnings: [
439
+ ...(write.warnings ?? []),
440
+ `changed only ${occurrenceLabel(state.cursor)} of "${state.title}" — the series itself is ` +
441
+ "unchanged",
442
+ nextDate === null
443
+ ? "the series has no further scheduled occurrence"
444
+ : `the next occurrence is ${nextDate}`,
445
+ IRREVERSIBLE_NOTE,
446
+ ],
447
+ };
448
+ });
449
+ }
450
+ export { PROJECT_REFUSAL, PROJECT_REMEDIATION };
451
+ //# sourceMappingURL=template-mutation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-mutation.js","sourceRoot":"","sources":["../../src/write/template-mutation.ts"],"names":[],"mappings":"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"}