things-api 0.9.0 → 0.11.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 (261) hide show
  1. package/README.md +57 -12
  2. package/dist/audit/log.js +56 -2
  3. package/dist/audit/log.js.map +1 -1
  4. package/dist/audit/schema.d.ts +26 -8
  5. package/dist/audit/schema.js +42 -1
  6. package/dist/audit/schema.js.map +1 -1
  7. package/dist/cli/clock.d.ts +8 -0
  8. package/dist/cli/clock.js +24 -0
  9. package/dist/cli/clock.js.map +1 -0
  10. package/dist/cli/commands/area.d.ts +26 -3
  11. package/dist/cli/commands/area.js +129 -75
  12. package/dist/cli/commands/area.js.map +1 -1
  13. package/dist/cli/commands/doctor.d.ts +1 -1
  14. package/dist/cli/commands/doctor.js +44 -5
  15. package/dist/cli/commands/doctor.js.map +1 -1
  16. package/dist/cli/commands/install-skill.d.ts +45 -0
  17. package/dist/cli/commands/install-skill.js +207 -0
  18. package/dist/cli/commands/install-skill.js.map +1 -0
  19. package/dist/cli/commands/mcp.js +23 -4
  20. package/dist/cli/commands/mcp.js.map +1 -1
  21. package/dist/cli/commands/project.d.ts +18 -1
  22. package/dist/cli/commands/project.js +74 -35
  23. package/dist/cli/commands/project.js.map +1 -1
  24. package/dist/cli/commands/reads.d.ts +15 -2
  25. package/dist/cli/commands/reads.js +459 -165
  26. package/dist/cli/commands/reads.js.map +1 -1
  27. package/dist/cli/commands/repeat-flags.d.ts +20 -0
  28. package/dist/cli/commands/repeat-flags.js +76 -0
  29. package/dist/cli/commands/repeat-flags.js.map +1 -0
  30. package/dist/cli/commands/setup.js +8 -4
  31. package/dist/cli/commands/setup.js.map +1 -1
  32. package/dist/cli/commands/show.js +53 -30
  33. package/dist/cli/commands/show.js.map +1 -1
  34. package/dist/cli/commands/todo.d.ts +1 -1
  35. package/dist/cli/commands/todo.js +20 -13
  36. package/dist/cli/commands/todo.js.map +1 -1
  37. package/dist/cli/commands/writes.js +388 -161
  38. package/dist/cli/commands/writes.js.map +1 -1
  39. package/dist/cli/did-you-mean.d.ts +1 -1
  40. package/dist/cli/excess-args.d.ts +15 -0
  41. package/dist/cli/excess-args.js +51 -0
  42. package/dist/cli/excess-args.js.map +1 -0
  43. package/dist/cli/glyphs.d.ts +55 -2
  44. package/dist/cli/glyphs.js +114 -21
  45. package/dist/cli/glyphs.js.map +1 -1
  46. package/dist/cli/help.d.ts +54 -0
  47. package/dist/cli/help.js +405 -0
  48. package/dist/cli/help.js.map +1 -0
  49. package/dist/cli/main.js +64 -26
  50. package/dist/cli/main.js.map +1 -1
  51. package/dist/cli/move-hint.d.ts +45 -0
  52. package/dist/cli/move-hint.js +196 -0
  53. package/dist/cli/move-hint.js.map +1 -0
  54. package/dist/cli/period.d.ts +9 -8
  55. package/dist/cli/period.js +56 -30
  56. package/dist/cli/period.js.map +1 -1
  57. package/dist/cli/read-driver.d.ts +26 -19
  58. package/dist/cli/read-driver.js +77 -33
  59. package/dist/cli/read-driver.js.map +1 -1
  60. package/dist/cli/render.d.ts +92 -28
  61. package/dist/cli/render.js +333 -103
  62. package/dist/cli/render.js.map +1 -1
  63. package/dist/cli/resolve-invocation.d.ts +42 -4
  64. package/dist/cli/resolve-invocation.js +97 -14
  65. package/dist/cli/resolve-invocation.js.map +1 -1
  66. package/dist/cli/skill-check.d.ts +21 -0
  67. package/dist/cli/skill-check.js +82 -0
  68. package/dist/cli/skill-check.js.map +1 -0
  69. package/dist/cli/skill.d.ts +62 -0
  70. package/dist/cli/skill.js +142 -0
  71. package/dist/cli/skill.js.map +1 -0
  72. package/dist/cli/tag-filters.d.ts +63 -0
  73. package/dist/cli/tag-filters.js +59 -0
  74. package/dist/cli/tag-filters.js.map +1 -0
  75. package/dist/cli/verb-hint.d.ts +25 -0
  76. package/dist/cli/verb-hint.js +163 -0
  77. package/dist/cli/verb-hint.js.map +1 -0
  78. package/dist/cli/version.d.ts +4 -0
  79. package/dist/cli/version.js +18 -0
  80. package/dist/cli/version.js.map +1 -0
  81. package/dist/cli/width.d.ts +135 -0
  82. package/dist/cli/width.js +313 -0
  83. package/dist/cli/width.js.map +1 -0
  84. package/dist/client.d.ts +160 -24
  85. package/dist/client.js +132 -19
  86. package/dist/client.js.map +1 -1
  87. package/dist/config.d.ts +11 -0
  88. package/dist/config.js +3 -0
  89. package/dist/config.js.map +1 -1
  90. package/dist/contracts.d.ts +97 -17
  91. package/dist/contracts.js +44 -1
  92. package/dist/contracts.js.map +1 -1
  93. package/dist/db/fingerprint.d.ts +12 -0
  94. package/dist/db/fingerprint.js +15 -1
  95. package/dist/db/fingerprint.js.map +1 -1
  96. package/dist/db/locate.js +1 -1
  97. package/dist/db/locate.js.map +1 -1
  98. package/dist/diagnose.d.ts +63 -0
  99. package/dist/diagnose.js +38 -1
  100. package/dist/diagnose.js.map +1 -1
  101. package/dist/index.d.ts +36 -5
  102. package/dist/index.js +38 -2
  103. package/dist/index.js.map +1 -1
  104. package/dist/mcp/server.d.ts +9 -1
  105. package/dist/mcp/server.js +1038 -436
  106. package/dist/mcp/server.js.map +1 -1
  107. package/dist/model/clock.d.ts +61 -0
  108. package/dist/model/clock.js +71 -0
  109. package/dist/model/clock.js.map +1 -0
  110. package/dist/model/dates.d.ts +26 -3
  111. package/dist/model/dates.js +84 -3
  112. package/dist/model/dates.js.map +1 -1
  113. package/dist/model/entities.d.ts +48 -10
  114. package/dist/model/entities.js.map +1 -1
  115. package/dist/model/mappers.d.ts +9 -2
  116. package/dist/model/mappers.js +32 -9
  117. package/dist/model/mappers.js.map +1 -1
  118. package/dist/model/serialize.d.ts +28 -0
  119. package/dist/model/serialize.js +80 -0
  120. package/dist/model/serialize.js.map +1 -0
  121. package/dist/model/when-sugar.d.ts +47 -0
  122. package/dist/model/when-sugar.js +45 -0
  123. package/dist/model/when-sugar.js.map +1 -0
  124. package/dist/read/area-view.d.ts +8 -1
  125. package/dist/read/area-view.js +55 -17
  126. package/dist/read/area-view.js.map +1 -1
  127. package/dist/read/detail.d.ts +1 -1
  128. package/dist/read/detail.js +11 -4
  129. package/dist/read/detail.js.map +1 -1
  130. package/dist/read/filter-contract.d.ts +117 -0
  131. package/dist/read/filter-contract.js +78 -0
  132. package/dist/read/filter-contract.js.map +1 -0
  133. package/dist/read/log-boundary.d.ts +1 -1
  134. package/dist/read/log-boundary.js +13 -3
  135. package/dist/read/log-boundary.js.map +1 -1
  136. package/dist/read/predicates.d.ts +30 -0
  137. package/dist/read/predicates.js +30 -0
  138. package/dist/read/predicates.js.map +1 -1
  139. package/dist/read/project-view.d.ts +12 -1
  140. package/dist/read/project-view.js +45 -12
  141. package/dist/read/project-view.js.map +1 -1
  142. package/dist/read/queries.d.ts +152 -7
  143. package/dist/read/queries.js +277 -36
  144. package/dist/read/queries.js.map +1 -1
  145. package/dist/read/sections.d.ts +51 -0
  146. package/dist/read/sections.js +37 -0
  147. package/dist/read/sections.js.map +1 -0
  148. package/dist/read/sidebar-order.js +2 -1
  149. package/dist/read/sidebar-order.js.map +1 -1
  150. package/dist/read/snapshot.d.ts +1 -1
  151. package/dist/read/snapshot.js +9 -2
  152. package/dist/read/snapshot.js.map +1 -1
  153. package/dist/read/tags.d.ts +27 -3
  154. package/dist/read/tags.js +83 -12
  155. package/dist/read/tags.js.map +1 -1
  156. package/dist/read/truncation.d.ts +71 -0
  157. package/dist/read/{pagination.js → truncation.js} +103 -94
  158. package/dist/read/truncation.js.map +1 -0
  159. package/dist/read/views.d.ts +147 -22
  160. package/dist/read/views.js +282 -80
  161. package/dist/read/views.js.map +1 -1
  162. package/dist/surface-copy.d.ts +19 -0
  163. package/dist/surface-copy.js +32 -0
  164. package/dist/surface-copy.js.map +1 -1
  165. package/dist/sync-health.d.ts +78 -0
  166. package/dist/sync-health.js +312 -0
  167. package/dist/sync-health.js.map +1 -0
  168. package/dist/write/accessibility-probe.d.ts +12 -0
  169. package/dist/write/accessibility-probe.js +71 -0
  170. package/dist/write/accessibility-probe.js.map +1 -0
  171. package/dist/write/automation-probe.d.ts +8 -1
  172. package/dist/write/automation-probe.js +16 -1
  173. package/dist/write/automation-probe.js.map +1 -1
  174. package/dist/write/batch.js +5 -2
  175. package/dist/write/batch.js.map +1 -1
  176. package/dist/write/capabilities.d.ts +8 -0
  177. package/dist/write/capabilities.js +13 -6
  178. package/dist/write/capabilities.js.map +1 -1
  179. package/dist/write/commands.d.ts +3 -1
  180. package/dist/write/commands.js +602 -49
  181. package/dist/write/commands.js.map +1 -1
  182. package/dist/write/edit-checklist.js +3 -2
  183. package/dist/write/edit-checklist.js.map +1 -1
  184. package/dist/write/guards.d.ts +2 -7
  185. package/dist/write/guards.js +87 -6
  186. package/dist/write/guards.js.map +1 -1
  187. package/dist/write/heading.js +2 -0
  188. package/dist/write/heading.js.map +1 -1
  189. package/dist/write/lock.d.ts +40 -2
  190. package/dist/write/lock.js +91 -14
  191. package/dist/write/lock.js.map +1 -1
  192. package/dist/write/make-repeating-project.d.ts +4 -0
  193. package/dist/write/make-repeating-project.js +253 -0
  194. package/dist/write/make-repeating-project.js.map +1 -0
  195. package/dist/write/operations.d.ts +145 -1
  196. package/dist/write/operations.js +48 -0
  197. package/dist/write/operations.js.map +1 -1
  198. package/dist/write/pipeline.d.ts +73 -2
  199. package/dist/write/pipeline.js +218 -43
  200. package/dist/write/pipeline.js.map +1 -1
  201. package/dist/write/planner.js +8 -1
  202. package/dist/write/planner.js.map +1 -1
  203. package/dist/write/pre-state.d.ts +105 -3
  204. package/dist/write/pre-state.js +144 -3
  205. package/dist/write/pre-state.js.map +1 -1
  206. package/dist/write/recurrence-rule-blob.d.ts +65 -0
  207. package/dist/write/recurrence-rule-blob.js +150 -0
  208. package/dist/write/recurrence-rule-blob.js.map +1 -0
  209. package/dist/write/reopen.js +3 -2
  210. package/dist/write/reopen.js.map +1 -1
  211. package/dist/write/reorder.js +27 -17
  212. package/dist/write/reorder.js.map +1 -1
  213. package/dist/write/repeat-rule.d.ts +22 -0
  214. package/dist/write/repeat-rule.js +258 -0
  215. package/dist/write/repeat-rule.js.map +1 -0
  216. package/dist/write/reversibility.js +49 -0
  217. package/dist/write/reversibility.js.map +1 -1
  218. package/dist/write/tag-refs.d.ts +47 -0
  219. package/dist/write/tag-refs.js +126 -0
  220. package/dist/write/tag-refs.js.map +1 -0
  221. package/dist/write/undo.d.ts +74 -5
  222. package/dist/write/undo.js +493 -80
  223. package/dist/write/undo.js.map +1 -1
  224. package/dist/write/vectors/registry.d.ts +15 -1
  225. package/dist/write/vectors/registry.js +65 -2
  226. package/dist/write/vectors/registry.js.map +1 -1
  227. package/dist/write/vectors/simulator.d.ts +44 -0
  228. package/dist/write/vectors/simulator.js +1136 -0
  229. package/dist/write/vectors/simulator.js.map +1 -0
  230. package/dist/write/vectors/types.d.ts +154 -3
  231. package/dist/write/vectors/ui-certification.d.ts +54 -0
  232. package/dist/write/vectors/ui-certification.js +43 -0
  233. package/dist/write/vectors/ui-certification.js.map +1 -0
  234. package/dist/write/vectors/ui-drag.d.ts +188 -0
  235. package/dist/write/vectors/ui-drag.js +1095 -0
  236. package/dist/write/vectors/ui-drag.js.map +1 -0
  237. package/dist/write/vectors/ui-recipes.d.ts +83 -0
  238. package/dist/write/vectors/ui-recipes.js +610 -0
  239. package/dist/write/vectors/ui-recipes.js.map +1 -0
  240. package/dist/write/vectors/ui.d.ts +152 -0
  241. package/dist/write/vectors/ui.js +704 -0
  242. package/dist/write/vectors/ui.js.map +1 -0
  243. package/dist/write/verify/delta.d.ts +141 -4
  244. package/dist/write/verify/delta.js +199 -21
  245. package/dist/write/verify/delta.js.map +1 -1
  246. package/dist/write/verify/poller.d.ts +7 -1
  247. package/dist/write/verify/poller.js +21 -1
  248. package/dist/write/verify/poller.js.map +1 -1
  249. package/package.json +18 -3
  250. package/skills/things-cli/SKILL.md +53 -0
  251. package/skills/things-cli/references/contracts.md +41 -0
  252. package/skills/things-cli/references/gui.md +11 -0
  253. package/skills/things-cli/references/model.md +51 -0
  254. package/dist/cli/exit-codes.d.ts +0 -26
  255. package/dist/cli/exit-codes.js +0 -26
  256. package/dist/cli/exit-codes.js.map +0 -1
  257. package/dist/cli/output.d.ts +0 -42
  258. package/dist/cli/output.js +0 -16
  259. package/dist/cli/output.js.map +0 -1
  260. package/dist/read/pagination.d.ts +0 -104
  261. package/dist/read/pagination.js.map +0 -1
@@ -4,8 +4,19 @@
4
4
  * per-vector matrices (data, produced by the lab), not here.
5
5
  */
6
6
  import type { IsoDate, ReminderTime } from "../model/dates.ts";
7
- export declare const OPERATION_KINDS: readonly ["todo.add", "todo.update", "todo.complete", "todo.cancel", "todo.reopen", "todo.move", "todo.set-tags", "todo.replace-checklist", "todo.edit-checklist-item", "todo.delete", "project.add", "project.update", "project.complete", "project.delete", "area.add", "area.delete", "tag.add", "tag.delete", "trash.empty", "reorder", "todo.duplicate", "area.update", "tag.update", "project.move", "todo.restore", "project.duplicate", "project.cancel", "project.reopen", "project.restore", "project.set-tags", "todo.backdate", "todo.add-logged", "heading.rename", "heading.archive", "heading.unarchive", "heading.create", "todo.clear-dated-reminder"];
7
+ export declare const OPERATION_KINDS: readonly ["todo.add", "todo.update", "todo.complete", "todo.cancel", "todo.reopen", "todo.move", "todo.set-tags", "todo.replace-checklist", "todo.edit-checklist-item", "todo.delete", "project.add", "project.update", "project.complete", "project.delete", "area.add", "area.delete", "tag.add", "tag.delete", "trash.empty", "reorder", "todo.duplicate", "area.update", "tag.update", "project.move", "todo.restore", "project.duplicate", "project.cancel", "project.reopen", "project.restore", "project.set-tags", "todo.backdate", "todo.add-logged", "heading.rename", "heading.archive", "heading.unarchive", "heading.create", "todo.clear-dated-reminder", "todo.make-repeating", "todo.reschedule-repeat", "todo.pause-repeat", "todo.resume-repeat", "todo.convert-to-project", "heading.convert-to-project", "project.reschedule-repeat", "project.pause-repeat", "project.resume-repeat", "area.reorder", "project.make-repeating", "project.create-repeating"];
8
8
  export type OperationKind = (typeof OPERATION_KINDS)[number];
9
+ /**
10
+ * Operations delivered EXCLUSIVELY through the Accessibility GUI ("ui")
11
+ * vector — GUI-only transforms with no headless spelling. Each drives the
12
+ * local Things app, so all are two-key gated: the `ui.enabled` config plus a
13
+ * per-call `dangerouslyDriveGui` acknowledgement (H-UI-DRIVE). Kept as data so
14
+ * the guard and the pipeline agree on the set.
15
+ */
16
+ export declare const UI_DRIVE_OPS: readonly OperationKind[];
17
+ export declare function isUiDriveOp(op: OperationKind): boolean;
18
+ /** Recurrence frequency the minimal v1 GUI rule vocabulary supports. */
19
+ export type RepeatFrequency = "daily" | "weekly" | "monthly" | "yearly";
9
20
  /** `when` scheduling value: list keyword or a concrete date. */
10
21
  export type WhenValue = "today" | "evening" | "anytime" | "someday" | IsoDate;
11
22
  /** Container reference by uuid or (unique, case-insensitive) title. */
@@ -271,6 +282,120 @@ export interface ReorderParams {
271
282
  strategy?: ReorderStrategy;
272
283
  }
273
284
  export type EmptyParams = Record<string, never>;
285
+ /**
286
+ * Move an area to a new position in the canonical area order. Area order has
287
+ * no headless spelling at all (P6/O13) — this is delivered by the ui vector's
288
+ * drag driver. Exactly ONE of before / after / position is required.
289
+ */
290
+ export interface AreaReorderParams {
291
+ /** The area to move: uuid or unique case-insensitive title. */
292
+ target: string;
293
+ /** Place it immediately ABOVE this area (uuid or unique title). */
294
+ before?: string;
295
+ /** Place it immediately BELOW this area (uuid or unique title). */
296
+ after?: string;
297
+ /** Move it to the first or last area slot. Exclusive with before/after. */
298
+ position?: "first" | "last";
299
+ }
300
+ /** Weekday name (weekly day-of-week set; monthly/yearly nth-weekday anchor). */
301
+ export type Weekday = "sunday" | "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday";
302
+ export declare const WEEKDAYS: readonly Weekday[];
303
+ /** The ordinal a monthly/yearly nth-weekday anchor selects (1st..5th, or last). */
304
+ export type WeekdayOrdinal = 1 | 2 | 3 | 4 | 5 | "last";
305
+ /**
306
+ * A monthly (or yearly) day anchor — the mutually-exclusive forms the Repeat
307
+ * dialog's month row offers (UIC1 field map). Exactly one shape:
308
+ * - `{ day }` — a day-of-month (1..31, or "last" = the month's last day);
309
+ * - `{ weekday, ordinal }` — the nth (or last) weekday of the month.
310
+ */
311
+ export type MonthlyAnchor = {
312
+ day: number | "last";
313
+ } | {
314
+ weekday: Weekday;
315
+ ordinal: WeekdayOrdinal;
316
+ };
317
+ /** A yearly anchor: a month (1..12) plus the monthly-style day anchor. */
318
+ export type YearlyAnchor = {
319
+ month: number;
320
+ } & MonthlyAnchor;
321
+ /**
322
+ * The Repeat dialog's "Ends" bound (single-choice pop-up, UIC1). Omit for the
323
+ * dialog default (`never`). `on-date` is the date picker; `after` the count
324
+ * field (the ORIGINAL number of occurrences, not the remaining tally).
325
+ */
326
+ export type RepeatEnds = {
327
+ kind: "never";
328
+ } | {
329
+ kind: "on-date";
330
+ date: IsoDate;
331
+ } | {
332
+ kind: "after";
333
+ count: number;
334
+ };
335
+ /**
336
+ * Set (make-repeating) or edit (reschedule-repeat) a to-do's or project's
337
+ * recurrence rule through the GUI's Repeat dialog. The BASE vocabulary is
338
+ * `frequency` + `interval`; every other field is OPTIONAL and defaults to the
339
+ * dialog's own default, so a `{ uuid, frequency, interval }` call is unchanged.
340
+ *
341
+ * The optional fields cover the full UIC1 dialog field map. Combinations are
342
+ * validated (assertRepeatRule): a per-frequency field on the wrong frequency is
343
+ * refused, and the modal month anchor is a discriminated shape (day-of-month OR
344
+ * nth-weekday, never a contradictory bag).
345
+ */
346
+ export interface RepeatRuleParams {
347
+ uuid: string;
348
+ /** The recurrence unit (also the "after completion" cadence when afterCompletion). */
349
+ frequency: RepeatFrequency;
350
+ /** "every N units", 1–99. */
351
+ interval: number;
352
+ /**
353
+ * After-COMPLETION cadence instead of a fixed schedule (rule type tp=1): the
354
+ * next occurrence is N units after the prior instance RESOLVES. Mutually
355
+ * exclusive with the calendar anchors (weekdays/monthly/yearly) — an
356
+ * after-completion rule has no calendar day.
357
+ */
358
+ afterCompletion?: boolean;
359
+ /**
360
+ * WEEKLY only: the set of weekdays the rule fires on (dialog day-of-week
361
+ * toggles + "+"). Omit for the single anchor weekday the dialog defaults to.
362
+ */
363
+ weekdays?: Weekday[];
364
+ /** MONTHLY only: the day-of-month or nth-weekday anchor (dialog month row). */
365
+ monthly?: MonthlyAnchor;
366
+ /** YEARLY only: the month + day anchor (dialog year row). */
367
+ yearly?: YearlyAnchor;
368
+ /** The "Ends" bound (dialog default: never). */
369
+ ends?: RepeatEnds;
370
+ /** "Add reminders" time-of-day (`HH:mm`, 24h) on the spawned instances. */
371
+ reminder?: ReminderTime;
372
+ /** "Add deadlines": the template deadlines its instances. */
373
+ deadline?: boolean;
374
+ /**
375
+ * With deadline: start the instance N days BEFORE its deadline (the dialog's
376
+ * "start N days earlier" field, revealed by "Add deadlines"). Integer ≥ 0;
377
+ * implies `deadline` (a start offset only exists on a deadlined template).
378
+ */
379
+ startDaysEarlier?: number;
380
+ }
381
+ /**
382
+ * Create a project and, in the same call, promote it to a repeating series
383
+ * (the two-step composite of UIC4-f). The create seeds a pure-AX taxonomy —
384
+ * an `area` lands the project as a selectable AREA-view row; otherwise it is
385
+ * created in Someday — so the promote never needs a coercion. The two legs are
386
+ * NOT atomic: the created project persists even if the promote refuses.
387
+ */
388
+ export interface ProjectCreateRepeatingParams {
389
+ title: string;
390
+ notes?: string;
391
+ /** Destination area (uuid or unique name); when omitted the project is created in Someday. */
392
+ area?: ContainerRef;
393
+ deadline?: IsoDate;
394
+ todos?: string[];
395
+ frequency: RepeatFrequency;
396
+ /** "every N units", 1–99. */
397
+ interval: number;
398
+ }
274
399
  export interface OperationParamsMap {
275
400
  "todo.add": TodoAddParams;
276
401
  "todo.update": TodoUpdateParams;
@@ -309,6 +434,18 @@ export interface OperationParamsMap {
309
434
  "heading.unarchive": HeadingUnarchiveParams;
310
435
  "heading.create": HeadingCreateParams;
311
436
  "todo.clear-dated-reminder": UuidParams;
437
+ "todo.make-repeating": RepeatRuleParams;
438
+ "todo.reschedule-repeat": RepeatRuleParams;
439
+ "todo.pause-repeat": UuidParams;
440
+ "todo.resume-repeat": UuidParams;
441
+ "todo.convert-to-project": UuidParams;
442
+ "heading.convert-to-project": UuidParams;
443
+ "project.reschedule-repeat": RepeatRuleParams;
444
+ "project.pause-repeat": UuidParams;
445
+ "project.resume-repeat": UuidParams;
446
+ "area.reorder": AreaReorderParams;
447
+ "project.make-repeating": RepeatRuleParams;
448
+ "project.create-repeating": ProjectCreateRepeatingParams;
312
449
  }
313
450
  /** Explicit confirmations for operations with cascading or permanent effects (never defaulted). */
314
451
  export interface Acknowledgements {
@@ -320,4 +457,11 @@ export interface Acknowledgements {
320
457
  dangerouslyPermanent?: boolean;
321
458
  /** Confirm that deleting a parent tag permanently deletes ALL of its descendant tags. */
322
459
  acknowledgeTagSubtree?: boolean;
460
+ /**
461
+ * Confirm a GUI-driven ("ui" vector) operation: it drives the LOCAL Things
462
+ * app through the Accessibility API, may foreground Things and briefly take
463
+ * over UI focus on this machine, and requires an unlocked session. The
464
+ * second of the two keys (the first is the `ui.enabled` config).
465
+ */
466
+ dangerouslyDriveGui?: boolean;
323
467
  }
@@ -36,5 +36,53 @@ export const OPERATION_KINDS = [
36
36
  "heading.unarchive",
37
37
  "heading.create",
38
38
  "todo.clear-dated-reminder",
39
+ "todo.make-repeating",
40
+ "todo.reschedule-repeat",
41
+ "todo.pause-repeat",
42
+ "todo.resume-repeat",
43
+ "todo.convert-to-project",
44
+ "heading.convert-to-project",
45
+ "project.reschedule-repeat",
46
+ "project.pause-repeat",
47
+ "project.resume-repeat",
48
+ "area.reorder",
49
+ "project.make-repeating",
50
+ "project.create-repeating",
51
+ ];
52
+ /**
53
+ * Operations delivered EXCLUSIVELY through the Accessibility GUI ("ui")
54
+ * vector — GUI-only transforms with no headless spelling. Each drives the
55
+ * local Things app, so all are two-key gated: the `ui.enabled` config plus a
56
+ * per-call `dangerouslyDriveGui` acknowledgement (H-UI-DRIVE). Kept as data so
57
+ * the guard and the pipeline agree on the set.
58
+ */
59
+ export const UI_DRIVE_OPS = [
60
+ "todo.make-repeating",
61
+ "todo.reschedule-repeat",
62
+ "todo.pause-repeat",
63
+ "todo.resume-repeat",
64
+ "todo.convert-to-project",
65
+ "heading.convert-to-project",
66
+ "project.reschedule-repeat",
67
+ "project.pause-repeat",
68
+ "project.resume-repeat",
69
+ "area.reorder",
70
+ // Pure-AX (UIC4): the project is selected as a content-table ROW via a
71
+ // settable AXSelectedRows, then Items ▸ Repeat… drives the same dialog. The
72
+ // area-less-anytime taxonomy needs a Someday coercion first, orchestrated by
73
+ // runMakeRepeatingProject — but the drive itself is a ui-vector op.
74
+ "project.make-repeating",
75
+ ];
76
+ export function isUiDriveOp(op) {
77
+ return UI_DRIVE_OPS.includes(op);
78
+ }
79
+ export const WEEKDAYS = [
80
+ "sunday",
81
+ "monday",
82
+ "tuesday",
83
+ "wednesday",
84
+ "thursday",
85
+ "friday",
86
+ "saturday",
39
87
  ];
40
88
  //# sourceMappingURL=operations.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"operations.js","sourceRoot":"","sources":["../../src/write/operations.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,UAAU;IACV,aAAa;IACb,eAAe;IACf,aAAa;IACb,aAAa;IACb,WAAW;IACX,eAAe;IACf,wBAAwB;IACxB,0BAA0B;IAC1B,aAAa;IACb,aAAa;IACb,gBAAgB;IAChB,kBAAkB;IAClB,gBAAgB;IAChB,UAAU;IACV,aAAa;IACb,SAAS;IACT,YAAY;IACZ,aAAa;IACb,SAAS;IACT,gBAAgB;IAChB,aAAa;IACb,YAAY;IACZ,cAAc;IACd,cAAc;IACd,mBAAmB;IACnB,gBAAgB;IAChB,gBAAgB;IAChB,iBAAiB;IACjB,kBAAkB;IAClB,eAAe;IACf,iBAAiB;IACjB,gBAAgB;IAChB,iBAAiB;IACjB,mBAAmB;IACnB,gBAAgB;IAChB,2BAA2B;CACnB,CAAC"}
1
+ {"version":3,"file":"operations.js","sourceRoot":"","sources":["../../src/write/operations.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,UAAU;IACV,aAAa;IACb,eAAe;IACf,aAAa;IACb,aAAa;IACb,WAAW;IACX,eAAe;IACf,wBAAwB;IACxB,0BAA0B;IAC1B,aAAa;IACb,aAAa;IACb,gBAAgB;IAChB,kBAAkB;IAClB,gBAAgB;IAChB,UAAU;IACV,aAAa;IACb,SAAS;IACT,YAAY;IACZ,aAAa;IACb,SAAS;IACT,gBAAgB;IAChB,aAAa;IACb,YAAY;IACZ,cAAc;IACd,cAAc;IACd,mBAAmB;IACnB,gBAAgB;IAChB,gBAAgB;IAChB,iBAAiB;IACjB,kBAAkB;IAClB,eAAe;IACf,iBAAiB;IACjB,gBAAgB;IAChB,iBAAiB;IACjB,mBAAmB;IACnB,gBAAgB;IAChB,2BAA2B;IAC3B,qBAAqB;IACrB,wBAAwB;IACxB,mBAAmB;IACnB,oBAAoB;IACpB,yBAAyB;IACzB,4BAA4B;IAC5B,2BAA2B;IAC3B,sBAAsB;IACtB,uBAAuB;IACvB,cAAc;IACd,wBAAwB;IACxB,0BAA0B;CAClB,CAAC;AAIX;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,YAAY,GAA6B;IACpD,qBAAqB;IACrB,wBAAwB;IACxB,mBAAmB;IACnB,oBAAoB;IACpB,yBAAyB;IACzB,4BAA4B;IAC5B,2BAA2B;IAC3B,sBAAsB;IACtB,uBAAuB;IACvB,cAAc;IACd,uEAAuE;IACvE,4EAA4E;IAC5E,6EAA6E;IAC7E,oEAAoE;IACpE,wBAAwB;CAChB,CAAC;AAEX,MAAM,UAAU,WAAW,CAAC,EAAiB;IAC3C,OAAO,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACnC,CAAC;AA+UD,MAAM,CAAC,MAAM,QAAQ,GAAuB;IAC1C,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,WAAW;IACX,UAAU;IACV,QAAQ;IACR,UAAU;CACF,CAAC"}
@@ -8,7 +8,7 @@ import { type LikelyCause } from "./failure-hints.ts";
8
8
  import { type HazardId } from "./guards.ts";
9
9
  import type { Acknowledgements, OperationKind, OperationParamsMap } from "./operations.ts";
10
10
  import type { VectorId, WriteVector } from "./vectors/types.ts";
11
- import { type DeltaSpec } from "./verify/delta.ts";
11
+ import { type DeltaSpec, type RepeatingDiscovery } from "./verify/delta.ts";
12
12
  import { type PollerDeps } from "./verify/poller.ts";
13
13
  export interface WriteOptions extends Acknowledgements {
14
14
  /** Caps vector selection; defaults from the config profile. */
@@ -18,6 +18,13 @@ export interface WriteOptions extends Acknowledgements {
18
18
  verifyTimeoutMs?: number;
19
19
  /** Return the plan without executing (nothing is audited). */
20
20
  dryRun?: boolean;
21
+ /**
22
+ * Create any tag named in this op's tags that does not exist yet (through the
23
+ * clean `make new tag` path, mkdir-p for `parent/child`) BEFORE applying —
24
+ * turning what would be an H-UNKNOWN-TAG refusal into a create-then-apply.
25
+ * Handled by the client's tag-prep orchestrator, above `runMutation`.
26
+ */
27
+ createTags?: boolean;
21
28
  /** Audit attribution. */
22
29
  actor?: string;
23
30
  /** Compound-operation grouping (set by orchestrators, not callers). */
@@ -25,6 +32,26 @@ export interface WriteOptions extends Acknowledgements {
25
32
  id: string;
26
33
  role: "leg" | "summary";
27
34
  };
35
+ /**
36
+ * Undo back-reference (set by the undo executor, not callers): the token of
37
+ * the original mutation this write inverts. Recorded on the audit trail so an
38
+ * already-undone mutation is distinguishable from a nonexistent one.
39
+ */
40
+ undoOf?: string;
41
+ /**
42
+ * Consumer IANA zone for THIS write, overriding the client's default zone.
43
+ * Only affects the clock-relative `when` tokens (today/evening) when
44
+ * {@link normalizeWhen} is set. Reminder times stay wall-clock and untranslated.
45
+ */
46
+ zone?: string;
47
+ /**
48
+ * Normalize a CONSUMER-provided clock-relative `when` (today/evening) to the
49
+ * effective consumer zone BEFORE dispatch — set by the consumer entry points
50
+ * (the client's `run`, batch), NEVER by the internal orchestrators (undo,
51
+ * reorder), whose when tokens converse with app-written host state and must
52
+ * stay on the host clock.
53
+ */
54
+ normalizeWhen?: boolean;
28
55
  }
29
56
  export interface MutationPlan {
30
57
  op: OperationKind;
@@ -41,6 +68,21 @@ export type MutationResult = {
41
68
  observed: Record<string, unknown> | null;
42
69
  vector: VectorId;
43
70
  tier: DisruptionTier;
71
+ /**
72
+ * The undo token for this mutation (ADDITIVE): pass it to
73
+ * `things undo --txn <token>` (MCP `txn`) to invert exactly this change,
74
+ * unaffected by any other mutations made in between.
75
+ */
76
+ undoToken?: string;
77
+ /**
78
+ * Make-repeating conversions (todo/project make-repeating, and
79
+ * project.create-repeating via its promote leg): the discovered template
80
+ * uuid, the FK-derived current-occurrence instance (use this for the
81
+ * VISIBLE item), and the replaced original uuid — plus `childrenReplaced`
82
+ * for project conversions. `uuid` still equals `templateUuid` (use it to
83
+ * reschedule the repeat). Absent for every other op.
84
+ */
85
+ repeating?: RepeatingDiscovery;
44
86
  /** Advisory notes (e.g. a changed environment tuple — consent may re-prompt later). */
45
87
  warnings?: string[];
46
88
  } | {
@@ -56,7 +98,7 @@ export type MutationResult = {
56
98
  } | {
57
99
  kind: "blocked";
58
100
  op: OperationKind;
59
- reason: "hazard" | "disruption-tier" | "drift" | "lock" | "environment";
101
+ reason: "hazard" | "disruption-tier" | "drift" | "lock" | "environment" | "clock";
60
102
  hazard?: HazardId;
61
103
  detail: string;
62
104
  remediation: string;
@@ -92,9 +134,38 @@ export interface WriteDeps {
92
134
  /** Seam: installed Things proxy shortcuts, for the pre-dispatch availability gate (availability.ts). */
93
135
  shortcutProxies?: () => ShortcutsState;
94
136
  now?: () => Date;
137
+ /** Default consumer IANA zone (client-resolved from THINGS_TZ); normalizes consumer `when` tokens. */
138
+ zone?: string;
95
139
  poller?: PollerDeps;
96
140
  pkgVersion?: string;
97
141
  }
98
142
  export declare function readAuthToken(db: DatabaseSync): string | null;
143
+ /**
144
+ * Normalize a CONSUMER-provided clock-relative `when` for the effective zone,
145
+ * so the app (which would interpret the bare word on the HOST clock) never sees
146
+ * a relative token that means a different calendar date for the consumer.
147
+ *
148
+ * - `today` → the consumer-zone calendar date, dispatched as an explicit
149
+ * `when=YYYY-MM-DD` (with any reminder still appended) so verification agrees
150
+ * by construction. When the consumer's today already equals the app's today
151
+ * the token is left as-is (byte-identical dispatch). A consumer-today that is
152
+ * host-yesterday yields a past startDate — coherent (lands in Today with
153
+ * overdue-start semantics), documented, not special-cased.
154
+ * - `evening` → This Evening exists ONLY for the app machine's own current day
155
+ * (the startBucket=1 rows whose startDate is exactly the app's today; an
156
+ * "evening of another day" is not representable in Things' model, not even in
157
+ * the GUI — see src/read/views.ts). Refused fail-closed when the dates differ.
158
+ *
159
+ * Reminder times are wall-clock and tz-less in Things' own model — never
160
+ * translated here.
161
+ */
162
+ export declare function normalizeConsumerWhen(params: Record<string, unknown>, now: Date, zone: string): {
163
+ ok: true;
164
+ params: Record<string, unknown>;
165
+ } | {
166
+ ok: false;
167
+ detail: string;
168
+ remediation: string;
169
+ };
99
170
  export declare function runMutation<K extends OperationKind>(deps: WriteDeps, op: K, params: OperationParamsMap[K], options?: WriteOptions): Promise<MutationResult>;
100
171
  export declare function fingerprintLabel(fp: FingerprintStatus, config: ThingsApiConfig): "ok" | "drift" | "user-accepted" | "unknown";