things-api 0.10.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (239) hide show
  1. package/README.md +50 -13
  2. package/dist/audit/schema.d.ts +7 -0
  3. package/dist/audit/schema.js.map +1 -1
  4. package/dist/cli/clock.d.ts +8 -0
  5. package/dist/cli/clock.js +24 -0
  6. package/dist/cli/clock.js.map +1 -0
  7. package/dist/cli/commands/area.d.ts +18 -11
  8. package/dist/cli/commands/area.js +61 -74
  9. package/dist/cli/commands/area.js.map +1 -1
  10. package/dist/cli/commands/doctor.d.ts +1 -2
  11. package/dist/cli/commands/doctor.js +11 -1
  12. package/dist/cli/commands/doctor.js.map +1 -1
  13. package/dist/cli/commands/install-skill.d.ts +60 -0
  14. package/dist/cli/commands/install-skill.js +256 -0
  15. package/dist/cli/commands/install-skill.js.map +1 -0
  16. package/dist/cli/commands/mcp.js +9 -0
  17. package/dist/cli/commands/mcp.js.map +1 -1
  18. package/dist/cli/commands/project.d.ts +1 -0
  19. package/dist/cli/commands/project.js +27 -34
  20. package/dist/cli/commands/project.js.map +1 -1
  21. package/dist/cli/commands/reads.d.ts +15 -2
  22. package/dist/cli/commands/reads.js +144 -44
  23. package/dist/cli/commands/reads.js.map +1 -1
  24. package/dist/cli/commands/setup.js +7 -2
  25. package/dist/cli/commands/setup.js.map +1 -1
  26. package/dist/cli/commands/show.js +38 -14
  27. package/dist/cli/commands/show.js.map +1 -1
  28. package/dist/cli/commands/todo.js +15 -9
  29. package/dist/cli/commands/todo.js.map +1 -1
  30. package/dist/cli/commands/writes.js +797 -174
  31. package/dist/cli/commands/writes.js.map +1 -1
  32. package/dist/cli/did-you-mean.d.ts +14 -3
  33. package/dist/cli/did-you-mean.js +26 -3
  34. package/dist/cli/did-you-mean.js.map +1 -1
  35. package/dist/cli/glyphs.d.ts +32 -2
  36. package/dist/cli/glyphs.js +83 -12
  37. package/dist/cli/glyphs.js.map +1 -1
  38. package/dist/cli/help.js +121 -16
  39. package/dist/cli/help.js.map +1 -1
  40. package/dist/cli/main.js +33 -2
  41. package/dist/cli/main.js.map +1 -1
  42. package/dist/cli/move-hint.d.ts +46 -0
  43. package/dist/cli/move-hint.js +196 -0
  44. package/dist/cli/move-hint.js.map +1 -0
  45. package/dist/cli/period.d.ts +2 -8
  46. package/dist/cli/period.js +44 -30
  47. package/dist/cli/period.js.map +1 -1
  48. package/dist/cli/read-driver.d.ts +43 -5
  49. package/dist/cli/read-driver.js +91 -15
  50. package/dist/cli/read-driver.js.map +1 -1
  51. package/dist/cli/render.d.ts +19 -8
  52. package/dist/cli/render.js +70 -27
  53. package/dist/cli/render.js.map +1 -1
  54. package/dist/cli/resolve-invocation.d.ts +2 -2
  55. package/dist/cli/resolve-invocation.js +3 -3
  56. package/dist/cli/resolve-invocation.js.map +1 -1
  57. package/dist/cli/skill-check.d.ts +27 -0
  58. package/dist/cli/skill-check.js +99 -0
  59. package/dist/cli/skill-check.js.map +1 -0
  60. package/dist/cli/skill.d.ts +70 -0
  61. package/dist/cli/skill.js +152 -0
  62. package/dist/cli/skill.js.map +1 -0
  63. package/dist/cli/tag-filters.d.ts +6 -2
  64. package/dist/cli/tag-filters.js +8 -6
  65. package/dist/cli/tag-filters.js.map +1 -1
  66. package/dist/cli/verb-hint.js +28 -3
  67. package/dist/cli/verb-hint.js.map +1 -1
  68. package/dist/cli/version.d.ts +4 -0
  69. package/dist/cli/version.js +18 -0
  70. package/dist/cli/version.js.map +1 -0
  71. package/dist/client.d.ts +171 -27
  72. package/dist/client.js +279 -40
  73. package/dist/client.js.map +1 -1
  74. package/dist/config.d.ts +66 -2
  75. package/dist/config.js +120 -12
  76. package/dist/config.js.map +1 -1
  77. package/dist/contracts.d.ts +186 -28
  78. package/dist/contracts.js +22 -1
  79. package/dist/contracts.js.map +1 -1
  80. package/dist/diagnose.d.ts +34 -2
  81. package/dist/diagnose.js +36 -1
  82. package/dist/diagnose.js.map +1 -1
  83. package/dist/index.d.ts +25 -9
  84. package/dist/index.js +22 -3
  85. package/dist/index.js.map +1 -1
  86. package/dist/mcp/server.d.ts +9 -0
  87. package/dist/mcp/server.js +1157 -684
  88. package/dist/mcp/server.js.map +1 -1
  89. package/dist/model/clock.d.ts +61 -0
  90. package/dist/model/clock.js +71 -0
  91. package/dist/model/clock.js.map +1 -0
  92. package/dist/model/dates.d.ts +26 -3
  93. package/dist/model/dates.js +84 -3
  94. package/dist/model/dates.js.map +1 -1
  95. package/dist/model/entities.d.ts +60 -3
  96. package/dist/model/entities.js.map +1 -1
  97. package/dist/model/mappers.d.ts +4 -2
  98. package/dist/model/mappers.js +66 -9
  99. package/dist/model/mappers.js.map +1 -1
  100. package/dist/model/recurrence.d.ts +8 -1
  101. package/dist/model/recurrence.js.map +1 -1
  102. package/dist/read/area-filter.d.ts +76 -0
  103. package/dist/read/area-filter.js +59 -0
  104. package/dist/read/area-filter.js.map +1 -0
  105. package/dist/read/area-view.d.ts +12 -12
  106. package/dist/read/area-view.js +58 -34
  107. package/dist/read/area-view.js.map +1 -1
  108. package/dist/read/detail.d.ts +1 -1
  109. package/dist/read/detail.js +26 -12
  110. package/dist/read/detail.js.map +1 -1
  111. package/dist/read/log-boundary.d.ts +1 -1
  112. package/dist/read/log-boundary.js +13 -3
  113. package/dist/read/log-boundary.js.map +1 -1
  114. package/dist/read/predicates.d.ts +18 -0
  115. package/dist/read/predicates.js +19 -0
  116. package/dist/read/predicates.js.map +1 -1
  117. package/dist/read/project-view.d.ts +32 -16
  118. package/dist/read/project-view.js +80 -45
  119. package/dist/read/project-view.js.map +1 -1
  120. package/dist/read/pseudo-area.d.ts +29 -0
  121. package/dist/read/pseudo-area.js +27 -0
  122. package/dist/read/pseudo-area.js.map +1 -0
  123. package/dist/read/queries.d.ts +108 -19
  124. package/dist/read/queries.js +212 -35
  125. package/dist/read/queries.js.map +1 -1
  126. package/dist/read/scope.d.ts +126 -0
  127. package/dist/read/scope.js +162 -0
  128. package/dist/read/scope.js.map +1 -0
  129. package/dist/read/search-rank.d.ts +2 -5
  130. package/dist/read/shape.d.ts +162 -0
  131. package/dist/read/shape.js +686 -0
  132. package/dist/read/shape.js.map +1 -0
  133. package/dist/read/show-target.d.ts +9 -1
  134. package/dist/read/show-target.js +45 -4
  135. package/dist/read/show-target.js.map +1 -1
  136. package/dist/read/snapshot.d.ts +1 -1
  137. package/dist/read/snapshot.js +9 -2
  138. package/dist/read/snapshot.js.map +1 -1
  139. package/dist/read/stage.d.ts +199 -0
  140. package/dist/read/stage.js +125 -0
  141. package/dist/read/stage.js.map +1 -0
  142. package/dist/read/truncation.d.ts +8 -6
  143. package/dist/read/truncation.js +35 -10
  144. package/dist/read/truncation.js.map +1 -1
  145. package/dist/read/views.d.ts +61 -20
  146. package/dist/read/views.js +240 -82
  147. package/dist/read/views.js.map +1 -1
  148. package/dist/surface-copy.d.ts +9 -0
  149. package/dist/surface-copy.js +9 -0
  150. package/dist/surface-copy.js.map +1 -1
  151. package/dist/write/accessibility-probe.d.ts +1 -1
  152. package/dist/write/accessibility-probe.js +8 -0
  153. package/dist/write/accessibility-probe.js.map +1 -1
  154. package/dist/write/automation-probe.d.ts +1 -1
  155. package/dist/write/automation-probe.js +8 -0
  156. package/dist/write/automation-probe.js.map +1 -1
  157. package/dist/write/batch.d.ts +49 -10
  158. package/dist/write/batch.js +423 -70
  159. package/dist/write/batch.js.map +1 -1
  160. package/dist/write/commands.d.ts +1 -1
  161. package/dist/write/commands.js +316 -66
  162. package/dist/write/commands.js.map +1 -1
  163. package/dist/write/guards.d.ts +1 -1
  164. package/dist/write/guards.js +94 -10
  165. package/dist/write/guards.js.map +1 -1
  166. package/dist/write/heading.d.ts +10 -1
  167. package/dist/write/heading.js +35 -5
  168. package/dist/write/heading.js.map +1 -1
  169. package/dist/write/make-repeating-project.d.ts +2 -2
  170. package/dist/write/make-repeating-project.js +9 -9
  171. package/dist/write/make-repeating-project.js.map +1 -1
  172. package/dist/write/move.d.ts +130 -0
  173. package/dist/write/move.js +1533 -0
  174. package/dist/write/move.js.map +1 -0
  175. package/dist/write/operations.d.ts +105 -19
  176. package/dist/write/operations.js +56 -7
  177. package/dist/write/operations.js.map +1 -1
  178. package/dist/write/opid.d.ts +31 -0
  179. package/dist/write/opid.js +30 -0
  180. package/dist/write/opid.js.map +1 -0
  181. package/dist/write/pipeline.d.ts +122 -3
  182. package/dist/write/pipeline.js +309 -52
  183. package/dist/write/pipeline.js.map +1 -1
  184. package/dist/write/planner.js +8 -1
  185. package/dist/write/planner.js.map +1 -1
  186. package/dist/write/pre-state.d.ts +197 -6
  187. package/dist/write/pre-state.js +427 -20
  188. package/dist/write/pre-state.js.map +1 -1
  189. package/dist/write/recurrence-rule-blob.d.ts +65 -0
  190. package/dist/write/recurrence-rule-blob.js +150 -0
  191. package/dist/write/recurrence-rule-blob.js.map +1 -0
  192. package/dist/write/reorder.d.ts +23 -3
  193. package/dist/write/reorder.js +1871 -85
  194. package/dist/write/reorder.js.map +1 -1
  195. package/dist/write/reversibility.js +19 -7
  196. package/dist/write/reversibility.js.map +1 -1
  197. package/dist/write/scope-guard.d.ts +31 -0
  198. package/dist/write/scope-guard.js +162 -0
  199. package/dist/write/scope-guard.js.map +1 -0
  200. package/dist/write/undo.js +120 -13
  201. package/dist/write/undo.js.map +1 -1
  202. package/dist/write/vectors/applescript.js +16 -7
  203. package/dist/write/vectors/applescript.js.map +1 -1
  204. package/dist/write/vectors/registry.d.ts +5 -7
  205. package/dist/write/vectors/registry.js +49 -2
  206. package/dist/write/vectors/registry.js.map +1 -1
  207. package/dist/write/vectors/shortcuts.js +1 -1
  208. package/dist/write/vectors/shortcuts.js.map +1 -1
  209. package/dist/write/vectors/simulator.d.ts +44 -0
  210. package/dist/write/vectors/simulator.js +1192 -0
  211. package/dist/write/vectors/simulator.js.map +1 -0
  212. package/dist/write/vectors/types.d.ts +46 -0
  213. package/dist/write/vectors/ui-certification.d.ts +10 -4
  214. package/dist/write/vectors/ui-certification.js +43 -10
  215. package/dist/write/vectors/ui-certification.js.map +1 -1
  216. package/dist/write/vectors/ui-drag.d.ts +21 -1
  217. package/dist/write/vectors/ui-drag.js +138 -27
  218. package/dist/write/vectors/ui-drag.js.map +1 -1
  219. package/dist/write/vectors/ui-recipes.d.ts +34 -1
  220. package/dist/write/vectors/ui-recipes.js +217 -6
  221. package/dist/write/vectors/ui-recipes.js.map +1 -1
  222. package/dist/write/vectors/ui.d.ts +40 -1
  223. package/dist/write/vectors/ui.js +196 -39
  224. package/dist/write/vectors/ui.js.map +1 -1
  225. package/dist/write/verify/delta.d.ts +127 -2
  226. package/dist/write/verify/delta.js +255 -16
  227. package/dist/write/verify/delta.js.map +1 -1
  228. package/dist/write/verify/poller.d.ts +7 -1
  229. package/dist/write/verify/poller.js +20 -1
  230. package/dist/write/verify/poller.js.map +1 -1
  231. package/package.json +24 -3
  232. package/schema/envelope.schema.json +383 -0
  233. package/skills/things-cli/SKILL.md +70 -0
  234. package/skills/things-cli/references/banner.md +35 -0
  235. package/skills/things-cli/references/contracts.md +62 -0
  236. package/skills/things-cli/references/errors.md +49 -0
  237. package/skills/things-cli/references/gui.md +11 -0
  238. package/skills/things-cli/references/model.md +60 -0
  239. package/skills/things-cli/references/ordering.md +71 -0
@@ -1,14 +1,16 @@
1
1
  import type { DatabaseSync } from "node:sqlite";
2
2
  import type { AuditWriter } from "../audit/log.ts";
3
+ import { type AuditRecord } from "../audit/schema.ts";
3
4
  import type { DisruptionTier, ThingsApiConfig } from "../config.ts";
4
5
  import type { FingerprintStatus } from "../db/fingerprint.ts";
6
+ import { type ResolvedScope } from "../read/scope.ts";
5
7
  import { type ShortcutsState } from "./availability.ts";
6
8
  import { type EnvironmentTracker } from "./environment.ts";
7
9
  import { type LikelyCause } from "./failure-hints.ts";
8
10
  import { type HazardId } from "./guards.ts";
9
- import type { Acknowledgements, OperationKind, OperationParamsMap } from "./operations.ts";
11
+ import { type Acknowledgements, type OperationKind, type OperationParamsMap } from "./operations.ts";
10
12
  import type { VectorId, WriteVector } from "./vectors/types.ts";
11
- import { type DeltaSpec } from "./verify/delta.ts";
13
+ import { type DeltaSpec, type RepeatingDiscovery } from "./verify/delta.ts";
12
14
  import { type PollerDeps } from "./verify/poller.ts";
13
15
  export interface WriteOptions extends Acknowledgements {
14
16
  /** Caps vector selection; defaults from the config profile. */
@@ -18,6 +20,16 @@ export interface WriteOptions extends Acknowledgements {
18
20
  verifyTimeoutMs?: number;
19
21
  /** Return the plan without executing (nothing is audited). */
20
22
  dryRun?: boolean;
23
+ /**
24
+ * Skip the post-execute state VERIFY poll for this write, treating a clean
25
+ * transport (exit 0) as ok. Fail-loud on the transport itself is preserved (a
26
+ * nonzero exit / deadline still runs the recovery re-verify). Used by the
27
+ * bounce orchestrator for the transient AWAY/BACK legs of a `when=` round-trip:
28
+ * the intermediate someday state is not independently verified — one verify
29
+ * per item round-trip (the placed-position + when-restore delta) is asserted by
30
+ * the orchestrator at item completion instead (reordgaps-results.md BOUNCE2).
31
+ */
32
+ skipVerify?: boolean;
21
33
  /**
22
34
  * Create any tag named in this op's tags that does not exist yet (through the
23
35
  * clean `make new tag` path, mkdir-p for `parent/child`) BEFORE applying —
@@ -38,6 +50,29 @@ export interface WriteOptions extends Acknowledgements {
38
50
  * already-undone mutation is distinguishable from a nonexistent one.
39
51
  */
40
52
  undoOf?: string;
53
+ /**
54
+ * Client idempotency id — a batch line's `opId` (set by the batch
55
+ * orchestrator) OR a single mutation's `--op-id` (set by the client `run`
56
+ * entry). Recorded on the audit record so a resubmission carrying the same id
57
+ * is recognized as already-applied. Recording is additive and never affects
58
+ * dispatch; the single-op idempotency CHECK (skip-and-replay on a match) runs
59
+ * in the client `run` entry before this pipeline is reached.
60
+ */
61
+ opId?: string;
62
+ /**
63
+ * Consumer IANA zone for THIS write, overriding the client's default zone.
64
+ * Only affects the clock-relative `when` tokens (today/evening) when
65
+ * {@link normalizeWhen} is set. Reminder times stay wall-clock and untranslated.
66
+ */
67
+ zone?: string;
68
+ /**
69
+ * Normalize a CONSUMER-provided clock-relative `when` (today/evening) to the
70
+ * effective consumer zone BEFORE dispatch — set by the consumer entry points
71
+ * (the client's `run`, batch), NEVER by the internal orchestrators (undo,
72
+ * reorder), whose when tokens converse with app-written host state and must
73
+ * stay on the host clock.
74
+ */
75
+ normalizeWhen?: boolean;
41
76
  }
42
77
  export interface MutationPlan {
43
78
  op: OperationKind;
@@ -51,6 +86,13 @@ export type MutationResult = {
51
86
  kind: "ok";
52
87
  op: OperationKind;
53
88
  uuid: string | null;
89
+ /**
90
+ * The mutated item's title (ADDITIVE), when the op targets a single
91
+ * pre-existing item — its pre-write title, captured before the change.
92
+ * Lets a batch log confirm WHAT was mutated without a second read. Absent
93
+ * for create/reorder ops, which have no single pre-existing target.
94
+ */
95
+ title?: string;
54
96
  observed: Record<string, unknown> | null;
55
97
  vector: VectorId;
56
98
  tier: DisruptionTier;
@@ -60,8 +102,34 @@ export type MutationResult = {
60
102
  * unaffected by any other mutations made in between.
61
103
  */
62
104
  undoToken?: string;
105
+ /**
106
+ * Make-repeating conversions (todo/project make-repeating, and
107
+ * project.add-repeating via its promote leg): the discovered template
108
+ * uuid, the FK-derived current-occurrence instance (use this for the
109
+ * VISIBLE item), and the replaced original uuid — plus `childrenReplaced`
110
+ * for project conversions. `uuid` still equals `templateUuid` (use it to
111
+ * reschedule the repeat). Absent for every other op.
112
+ */
113
+ repeating?: RepeatingDiscovery;
63
114
  /** Advisory notes (e.g. a changed environment tuple — consent may re-prompt later). */
64
115
  warnings?: string[];
116
+ /**
117
+ * Co-bounced siblings (ADDITIVE): a bounce reorder that anchors a block
118
+ * with --before/--after (or lands it mid-bucket) must re-insert every
119
+ * UNNAMED member between the block and the bucket edge. Those items get a
120
+ * modification bump, a changes-feed entry, and an audit leg — disclosed
121
+ * here explicitly, never as fine print. Absent when only the named movees
122
+ * were touched.
123
+ */
124
+ touched?: string[];
125
+ /**
126
+ * Idempotency replay (ADDITIVE, presence-keyed): `true` when this result
127
+ * did NOT execute — a mutation carrying an `opId` matched a prior verified
128
+ * `ok` record with the same id in the recent change history, so the earlier
129
+ * change stands and nothing ran again. The `uuid`/`title`/`undoToken` echo
130
+ * the ORIGINAL mutation's identity. Absent on a normal (executed) result.
131
+ */
132
+ alreadyApplied?: true;
65
133
  } | {
66
134
  kind: "verify-failed";
67
135
  op: OperationKind;
@@ -75,7 +143,7 @@ export type MutationResult = {
75
143
  } | {
76
144
  kind: "blocked";
77
145
  op: OperationKind;
78
- reason: "hazard" | "disruption-tier" | "drift" | "lock" | "environment";
146
+ reason: "hazard" | "disruption-tier" | "drift" | "lock" | "environment" | "clock" | "scope";
79
147
  hazard?: HazardId;
80
148
  detail: string;
81
149
  remediation: string;
@@ -111,9 +179,60 @@ export interface WriteDeps {
111
179
  /** Seam: installed Things proxy shortcuts, for the pre-dispatch availability gate (availability.ts). */
112
180
  shortcutProxies?: () => ShortcutsState;
113
181
  now?: () => Date;
182
+ /** Default consumer IANA zone (client-resolved from THINGS_TZ); normalizes consumer `when` tokens. */
183
+ zone?: string;
184
+ /**
185
+ * The active container scope (pinned at openThings). When set: uuid targets
186
+ * resolve scope-aware (out-of-scope == not-found parity), and the universal
187
+ * scope gate (evaluateScope) runs before the hazard guards. Absent = unscoped.
188
+ */
189
+ scope?: ResolvedScope;
114
190
  poller?: PollerDeps;
115
191
  pkgVersion?: string;
192
+ /**
193
+ * Audit-trail directory (client-wired): read by `runBatch` for the opId
194
+ * idempotency lookback. Absent = no lookback (opId dedup is a no-op), which is
195
+ * the correct degraded behavior when the trail is unavailable.
196
+ */
197
+ auditDirPath?: string;
116
198
  }
117
199
  export declare function readAuthToken(db: DatabaseSync): string | null;
200
+ /**
201
+ * Normalize a CONSUMER-provided clock-relative `when` for the effective zone,
202
+ * so the app (which would interpret the bare word on the HOST clock) never sees
203
+ * a relative token that means a different calendar date for the consumer.
204
+ *
205
+ * - `today` → the consumer-zone calendar date, dispatched as an explicit
206
+ * `when=YYYY-MM-DD` (with any reminder still appended) so verification agrees
207
+ * by construction. When the consumer's today already equals the app's today
208
+ * the token is left as-is (byte-identical dispatch). A consumer-today that is
209
+ * host-yesterday yields a past startDate — coherent (lands in Today with
210
+ * overdue-start semantics), documented, not special-cased.
211
+ * - `evening` → This Evening exists ONLY for the app machine's own current day
212
+ * (the startBucket=1 rows whose startDate is exactly the app's today; an
213
+ * "evening of another day" is not representable in Things' model, not even in
214
+ * the GUI — see src/read/views.ts). Refused fail-closed when the dates differ.
215
+ *
216
+ * Reminder times are wall-clock and tz-less in Things' own model — never
217
+ * translated here.
218
+ */
219
+ export declare function normalizeConsumerWhen(params: Record<string, unknown>, now: Date, zone: string): {
220
+ ok: true;
221
+ params: Record<string, unknown>;
222
+ } | {
223
+ ok: false;
224
+ detail: string;
225
+ remediation: string;
226
+ };
118
227
  export declare function runMutation<K extends OperationKind>(deps: WriteDeps, op: K, params: OperationParamsMap[K], options?: WriteOptions): Promise<MutationResult>;
228
+ /**
229
+ * Build the single-op idempotency REPLAY result from the matched audit record —
230
+ * a `kind: "ok"` MutationResult that did not execute (`alreadyApplied: true`),
231
+ * echoing the ORIGINAL mutation's identity. Mirrors the pipeline's own
232
+ * result-shaping: the `undoToken` is surfaced under the SAME rule the executor
233
+ * uses (only for a non-leg, reversible op — an irreversible op or a batch leg
234
+ * carries none), and `title` rides `requested.title` when the record stored one
235
+ * (the audit record has no dedicated title field — see the trail-record note).
236
+ */
237
+ export declare function replayResultFromRecord(record: AuditRecord): MutationResult;
119
238
  export declare function fingerprintLabel(fp: FingerprintStatus, config: ThingsApiConfig): "ok" | "drift" | "user-accepted" | "unknown";