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
@@ -1 +1 @@
1
- {"version":3,"file":"heading.js","sourceRoot":"","sources":["../../src/write/heading.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"heading.js","sourceRoot":"","sources":["../../src/write/heading.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,48 @@
1
+ /**
2
+ * Advisory mutation lockfile: serializes mutations across concurrent CLI
3
+ * invocations so create-probe verification is never ambiguous (design §4).
4
+ * Stale locks (dead pid) are stolen; live locks are awaited with backoff.
5
+ *
6
+ * The steal is atomic: a stealer `rename`s the stale lockfile to a private
7
+ * temp name (rename succeeds for exactly one racer; every other racer gets
8
+ * ENOENT and falls back to the wait/retry loop), then re-reads the renamed
9
+ * file to confirm the holder is still dead before discarding it. This closes
10
+ * the TOCTOU window an unconditional unlink+recreate would leave open, where
11
+ * two processes could both observe a dead holder and both end up believing
12
+ * they hold the lock.
13
+ */
14
+ import { mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
1
15
  export declare class MutationLockError extends Error {
2
16
  constructor(message: string);
3
17
  }
4
18
  export interface MutationLock {
5
19
  release(): void;
6
20
  }
7
- export declare function acquireMutationLock(path: string, options?: {
21
+ /**
22
+ * Injectable filesystem + environment seam. Production uses the real node:fs
23
+ * calls; unit tests substitute this to drive the concurrent steal paths
24
+ * deterministically. Not part of the public contract — callers pass only the
25
+ * documented options below.
26
+ * @internal
27
+ */
28
+ export interface LockDeps {
29
+ mkdirSync: typeof mkdirSync;
30
+ readFileSync: typeof readFileSync;
31
+ writeFileSync: typeof writeFileSync;
32
+ renameSync: typeof renameSync;
33
+ unlinkSync: typeof unlinkSync;
34
+ pidAlive: (pid: number) => boolean;
35
+ pid: number;
36
+ now: () => string;
37
+ uniqueSuffix: () => string;
38
+ /** Test-only barrier, awaited after a dead holder is observed and before
39
+ * the steal `rename`. Inert (absent) in production. */
40
+ onBeforeSteal?: () => Promise<void> | void;
41
+ }
42
+ export interface AcquireMutationLockOptions {
8
43
  waitMs?: number;
9
44
  sleep?: (ms: number) => Promise<void>;
10
- }): Promise<MutationLock>;
45
+ /** @internal test seam — see {@link LockDeps}. */
46
+ deps?: LockDeps;
47
+ }
48
+ export declare function acquireMutationLock(path: string, options?: AcquireMutationLockOptions): Promise<MutationLock>;
@@ -2,8 +2,16 @@
2
2
  * Advisory mutation lockfile: serializes mutations across concurrent CLI
3
3
  * invocations so create-probe verification is never ambiguous (design §4).
4
4
  * Stale locks (dead pid) are stolen; live locks are awaited with backoff.
5
+ *
6
+ * The steal is atomic: a stealer `rename`s the stale lockfile to a private
7
+ * temp name (rename succeeds for exactly one racer; every other racer gets
8
+ * ENOENT and falls back to the wait/retry loop), then re-reads the renamed
9
+ * file to confirm the holder is still dead before discarding it. This closes
10
+ * the TOCTOU window an unconditional unlink+recreate would leave open, where
11
+ * two processes could both observe a dead holder and both end up believing
12
+ * they hold the lock.
5
13
  */
6
- import { mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
14
+ import { mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
7
15
  import { dirname } from "node:path";
8
16
  export class MutationLockError extends Error {
9
17
  constructor(message) {
@@ -20,19 +28,37 @@ function pidAlive(pid) {
20
28
  return false;
21
29
  }
22
30
  }
31
+ let stealCounter = 0;
32
+ function realDeps() {
33
+ return {
34
+ mkdirSync,
35
+ readFileSync,
36
+ writeFileSync,
37
+ renameSync,
38
+ unlinkSync,
39
+ pidAlive,
40
+ pid: process.pid,
41
+ now: () => new Date().toISOString(),
42
+ uniqueSuffix: () => `${Date.now().toString(36)}-${(stealCounter++).toString(36)}-${Math.random().toString(36).slice(2, 8)}`,
43
+ };
44
+ }
45
+ function errCode(err) {
46
+ return err.code;
47
+ }
23
48
  export async function acquireMutationLock(path, options = {}) {
24
49
  const waitMs = options.waitMs ?? 30_000;
25
50
  const sleep = options.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
51
+ const deps = options.deps ?? realDeps();
26
52
  const deadline = Date.now() + waitMs;
27
- mkdirSync(dirname(path), { recursive: true });
53
+ deps.mkdirSync(dirname(path), { recursive: true });
28
54
  for (;;) {
29
55
  try {
30
- const payload = { pid: process.pid, ts: new Date().toISOString() };
31
- writeFileSync(path, JSON.stringify(payload), { flag: "wx" });
56
+ const payload = { pid: deps.pid, ts: deps.now() };
57
+ deps.writeFileSync(path, JSON.stringify(payload), { flag: "wx" });
32
58
  return {
33
59
  release() {
34
60
  try {
35
- unlinkSync(path);
61
+ deps.unlinkSync(path);
36
62
  }
37
63
  catch {
38
64
  // already gone — fine
@@ -41,30 +67,81 @@ export async function acquireMutationLock(path, options = {}) {
41
67
  };
42
68
  }
43
69
  catch (err) {
44
- if (err.code !== "EEXIST")
70
+ if (errCode(err) !== "EEXIST")
45
71
  throw err;
46
72
  let holder = null;
47
73
  try {
48
- holder = JSON.parse(readFileSync(path, "utf8"));
74
+ holder = JSON.parse(deps.readFileSync(path, "utf8"));
49
75
  }
50
76
  catch {
51
77
  holder = null; // torn write — treat as stale
52
78
  }
53
- if (holder === null || !pidAlive(holder.pid)) {
54
- try {
55
- unlinkSync(path); // stale: holder is dead
56
- }
57
- catch {
58
- // raced another steal — loop and retry
59
- }
79
+ if (holder === null || !deps.pidAlive(holder.pid)) {
80
+ await stealStale(path, deps);
81
+ // Whatever the steal outcome, re-loop: an empty slot lets us create a
82
+ // fresh lock via `wx`; a slot re-taken by another process sends us
83
+ // back through the holder check (and, for a live holder, the wait).
60
84
  continue;
61
85
  }
62
86
  if (Date.now() >= deadline) {
63
87
  throw new MutationLockError(`another mutation is in progress (pid ${holder.pid} since ${holder.ts}); ` +
64
88
  `waited ${waitMs}ms for ${path}`);
65
89
  }
90
+ // lock-acquisition retries are inherently sequential polling against the same lockfile
66
91
  await sleep(150);
67
92
  }
68
93
  }
69
94
  }
95
+ /**
96
+ * Atomically claim and discard a lockfile whose holder appears dead. Exactly
97
+ * one concurrent stealer wins the `rename`; the rest get ENOENT and return to
98
+ * retry. After winning, the renamed file is re-read: if a live lock had been
99
+ * installed at `path` in the meantime (so the file we just moved is actually
100
+ * live), it is restored to `path` — via `wx`, so a lock re-created by a third
101
+ * process is never clobbered — and we back off instead of stealing it.
102
+ */
103
+ async function stealStale(path, deps) {
104
+ const temp = `${path}.steal-${deps.pid}-${deps.uniqueSuffix()}`;
105
+ if (deps.onBeforeSteal)
106
+ await deps.onBeforeSteal();
107
+ try {
108
+ deps.renameSync(path, temp);
109
+ }
110
+ catch (err) {
111
+ if (errCode(err) === "ENOENT")
112
+ return; // lost the rename race — retry
113
+ throw err;
114
+ }
115
+ // We won the rename and now own `temp`. Confirm the holder is still dead.
116
+ let stolen = null;
117
+ try {
118
+ stolen = JSON.parse(deps.readFileSync(temp, "utf8"));
119
+ }
120
+ catch {
121
+ stolen = null; // torn write — genuinely stale
122
+ }
123
+ if (stolen !== null && deps.pidAlive(stolen.pid)) {
124
+ // A live lock slipped in between our read and our rename: this file is not
125
+ // stale after all. Put it back for its holder (only if the slot is free)
126
+ // and back off.
127
+ try {
128
+ deps.writeFileSync(path, JSON.stringify(stolen), { flag: "wx" });
129
+ }
130
+ catch {
131
+ // slot already re-taken — leave the newcomer's lock intact
132
+ }
133
+ tryUnlink(deps, temp);
134
+ return;
135
+ }
136
+ // Confirmed stale — drop it so the next loop turn can create a fresh lock.
137
+ tryUnlink(deps, temp);
138
+ }
139
+ function tryUnlink(deps, path) {
140
+ try {
141
+ deps.unlinkSync(path);
142
+ }
143
+ catch {
144
+ // already gone — fine
145
+ }
146
+ }
70
147
  //# sourceMappingURL=lock.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lock.js","sourceRoot":"","sources":["../../src/write/lock.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAC1C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF;AAOD,SAAS,QAAQ,CAAC,GAAW;IAC3B,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAMD,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,IAAY,EACZ,UAAsE,EAAE;IAExE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC;IACxC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/E,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC;IACrC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE9C,SAAS,CAAC;QACR,IAAI,CAAC;YACH,MAAM,OAAO,GAAgB,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;YAChF,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7D,OAAO;gBACL,OAAO;oBACL,IAAI,CAAC;wBACH,UAAU,CAAC,IAAI,CAAC,CAAC;oBACnB,CAAC;oBAAC,MAAM,CAAC;wBACP,sBAAsB;oBACxB,CAAC;gBACH,CAAC;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;gBAAE,MAAM,GAAG,CAAC;YAChE,IAAI,MAAM,GAAuB,IAAI,CAAC;YACtC,IAAI,CAAC;gBACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAgB,CAAC;YACjE,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,GAAG,IAAI,CAAC,CAAC,8BAA8B;YAC/C,CAAC;YACD,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC7C,IAAI,CAAC;oBACH,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,wBAAwB;gBAC5C,CAAC;gBAAC,MAAM,CAAC;oBACP,uCAAuC;gBACzC,CAAC;gBACD,SAAS;YACX,CAAC;YACD,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,QAAQ,EAAE,CAAC;gBAC3B,MAAM,IAAI,iBAAiB,CACzB,wCAAwC,MAAM,CAAC,GAAG,UAAU,MAAM,CAAC,EAAE,KAAK;oBACxE,UAAU,MAAM,UAAU,IAAI,EAAE,CACnC,CAAC;YACJ,CAAC;YACD,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"lock.js","sourceRoot":"","sources":["../../src/write/lock.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { ProjectCreateRepeatingParams, RepeatRuleParams } from "./operations.ts";
2
+ import { type MutationResult, type WriteDeps, type WriteOptions } from "./pipeline.ts";
3
+ export declare function runMakeRepeatingProject(deps: WriteDeps, params: RepeatRuleParams, options?: WriteOptions): Promise<MutationResult>;
4
+ export declare function runCreateRepeatingProject(deps: WriteDeps, params: ProjectCreateRepeatingParams, options?: WriteOptions): Promise<MutationResult>;
@@ -0,0 +1,253 @@
1
+ import { resolveProjectWriteTarget } from "../read/queries.js";
2
+ import { assertRepeatRule } from "./commands.js";
3
+ import { classifyProjectRepeat, loadTarget } from "./pre-state.js";
4
+ import { fingerprintLabel, runMutation, } from "./pipeline.js";
5
+ /** The two-key GUI-drive block, shared by both orchestrators (mirrors H-UI-DRIVE). */
6
+ function blockedUiDrive(op) {
7
+ return {
8
+ kind: "blocked",
9
+ op,
10
+ reason: "hazard",
11
+ hazard: "H-UI-DRIVE",
12
+ detail: "this operation drives the local Things app through the Accessibility API — the project " +
13
+ "row-selection, menu press, and Repeat dialog all run through the Accessibility tree",
14
+ remediation: "pass dangerouslyDriveGui (--dangerously-drive-gui) to proceed; the vector also requires " +
15
+ "`things config set ui-enabled true` and Accessibility granted to this process (see docs/setup.md)",
16
+ };
17
+ }
18
+ /** Translate a refusal taxonomy into a blocked result (the guard's user-facing shape). */
19
+ function blockedRefusal(tax) {
20
+ if (tax.refusal === "not-a-project") {
21
+ return {
22
+ kind: "blocked",
23
+ op: "project.make-repeating",
24
+ reason: "hazard",
25
+ hazard: "H-UNKNOWN-DESTINATION",
26
+ detail: `${tax.detail} — project.make-repeating needs an existing project`,
27
+ remediation: "verify the uuid with `things projects`, or use `things todo make-repeating` for a to-do",
28
+ };
29
+ }
30
+ const remediation = tax.refusal === "ambiguous-row"
31
+ ? "rename one of the same-titled projects so the target's row is unambiguous"
32
+ : tax.refusal === "already-repeating"
33
+ ? "the project already repeats — use `things project reschedule-repeat` to change its rule"
34
+ : "target an open, un-trashed project";
35
+ return {
36
+ kind: "blocked",
37
+ op: "project.make-repeating",
38
+ reason: "hazard",
39
+ hazard: "H-PROJECT-REPEAT",
40
+ detail: tax.detail,
41
+ remediation,
42
+ };
43
+ }
44
+ /** A per-run txn id (matches the pipeline's leg/summary grouping). */
45
+ function newTxnId(now) {
46
+ return `txn-${now.getTime().toString(36)}-${process.pid.toString(36)}`;
47
+ }
48
+ /** Forward the caller's audit/timeout knobs onto a delegated leg. */
49
+ function legOptions(base, txn, vector) {
50
+ const out = { txn };
51
+ if (vector !== undefined)
52
+ out.vector = vector;
53
+ if (base.actor !== undefined)
54
+ out.actor = base.actor;
55
+ if (base.verifyTimeoutMs !== undefined)
56
+ out.verifyTimeoutMs = base.verifyTimeoutMs;
57
+ if (base.maxDisruption !== undefined)
58
+ out.maxDisruption = base.maxDisruption;
59
+ if (base.dangerouslyDriveGui !== undefined)
60
+ out.dangerouslyDriveGui = base.dangerouslyDriveGui;
61
+ return out;
62
+ }
63
+ export async function runMakeRepeatingProject(deps, params, options = {}) {
64
+ const uuid = resolveProjectWriteTarget(deps.db, params.uuid);
65
+ // Validate the rule BEFORE any coercion — a bad rule must never leave a
66
+ // coerced-to-someday project stranded.
67
+ assertRepeatRule(params);
68
+ const target = loadTarget(deps.db, uuid);
69
+ const tax = classifyProjectRepeat(deps.db, target);
70
+ if (tax.kind === "refuse")
71
+ return blockedRefusal(tax);
72
+ // The GUI-drive ack gates the coercion decision too: block before touching
73
+ // anything if it is missing (the delegated drive would block anyway, but the
74
+ // anytime path must not coerce first only to be blocked at the drive).
75
+ if (options.dangerouslyDriveGui !== true && options.dryRun !== true) {
76
+ return blockedUiDrive("project.make-repeating");
77
+ }
78
+ const driveParams = {
79
+ uuid,
80
+ frequency: params.frequency,
81
+ interval: params.interval,
82
+ ...(params.afterCompletion !== undefined && { afterCompletion: params.afterCompletion }),
83
+ ...(params.weekdays !== undefined && { weekdays: params.weekdays }),
84
+ ...(params.monthly !== undefined && { monthly: params.monthly }),
85
+ ...(params.yearly !== undefined && { yearly: params.yearly }),
86
+ ...(params.ends !== undefined && { ends: params.ends }),
87
+ ...(params.reminder !== undefined && { reminder: params.reminder }),
88
+ ...(params.deadline !== undefined && { deadline: params.deadline }),
89
+ ...(params.startDaysEarlier !== undefined && { startDaysEarlier: params.startDaysEarlier }),
90
+ };
91
+ if (options.dryRun === true) {
92
+ const coercion = tax.kind === "anytime"
93
+ ? `coerce to Someday (update-project?id=${uuid}&when=someday) → verified → `
94
+ : "";
95
+ const view = tax.kind === "area" ? `area ${tax.containerReveal}` : "Someday";
96
+ return {
97
+ kind: "dry-run",
98
+ op: "project.make-repeating",
99
+ plan: {
100
+ op: "project.make-repeating",
101
+ vector: "ui",
102
+ tier: 3,
103
+ invocation: `${coercion}reveal ${view} → select the project row (AXSelectedRows) → Items ▸ Repeat… → ` +
104
+ `frequency=${params.frequency}, interval=${params.interval} → OK`,
105
+ expectedDelta: {
106
+ mode: "create",
107
+ probe: { title: tax.title, type: "project", sinceEpoch: 0 },
108
+ assert: [{ field: "repeating.isTemplate", equals: true }],
109
+ },
110
+ hazardsChecked: ["H-UNKNOWN-DESTINATION", "H-PROJECT-REPEAT", "H-UI-DRIVE"],
111
+ },
112
+ };
113
+ }
114
+ // area / someday: no coercion — the single pure-AX drive IS the mutation.
115
+ if (tax.kind === "area" || tax.kind === "someday") {
116
+ return runMutation(deps, "project.make-repeating", driveParams, { ...options, vector: "ui" });
117
+ }
118
+ // area-less anytime: coerce to Someday (cleanup-free, UIC4-c/d) then drive,
119
+ // grouped as one txn with a single undoable SUMMARY record.
120
+ const startedAt = deps.now?.() ?? new Date();
121
+ const txnId = newTxnId(startedAt);
122
+ const coerce = await runMutation(deps, "project.update", { uuid, when: "someday" }, legOptions(options, { id: txnId, role: "leg" }, "url-scheme"));
123
+ if (coerce.kind !== "ok") {
124
+ // Nothing was promoted; the coercion itself failed or was blocked — surface it.
125
+ return coerce.kind === "blocked"
126
+ ? coerce
127
+ : {
128
+ kind: "verify-failed",
129
+ op: "project.make-repeating",
130
+ reason: coerce.kind === "verify-failed" ? coerce.reason : "mismatch",
131
+ expected: coerce.kind === "verify-failed"
132
+ ? coerce.expected
133
+ : { mode: "update", uuid, assert: [] },
134
+ observed: coerce.kind === "verify-failed" ? coerce.observed : null,
135
+ detail: "the Someday coercion (the intermediate step for an area-less Anytime project) failed — " +
136
+ "the project was NOT made repeating and its schedule is unchanged",
137
+ };
138
+ }
139
+ const drive = await runMutation(deps, "project.make-repeating", driveParams, legOptions(options, { id: txnId, role: "leg" }, "ui"));
140
+ if (drive.kind !== "ok") {
141
+ // Non-atomic residue: the project IS now in Someday but was not promoted.
142
+ // make-repeating normalizes start to someday anyway (UIC4-c), so this is not
143
+ // a corruption — just an incomplete op. Report it honestly.
144
+ return drive;
145
+ }
146
+ appendSummary(deps, {
147
+ startedAt,
148
+ uuid: drive.uuid,
149
+ txnId,
150
+ invocation: `make-repeating(project, coerced from anytime) id=${uuid} → template ${drive.uuid ?? "?"}`,
151
+ });
152
+ return { ...drive, ...(drive.warnings !== undefined && { warnings: drive.warnings }) };
153
+ }
154
+ export async function runCreateRepeatingProject(deps, params, options = {}) {
155
+ // create-repeating carries only the base rule vocabulary (the promote can be
156
+ // followed by a reschedule for a richer rule); validate just that.
157
+ assertRepeatRule({ frequency: params.frequency, interval: params.interval });
158
+ // The promote drives the GUI — block before creating anything if the ack is missing.
159
+ if (options.dangerouslyDriveGui !== true && options.dryRun !== true) {
160
+ return blockedUiDrive("project.create-repeating");
161
+ }
162
+ // Seed a pure-AX taxonomy: an area lands a selectable AREA-view row; otherwise
163
+ // create in Someday (UIC4-f) so the promote skips the anytime-header problem.
164
+ const seedWhen = params.area === undefined ? "someday" : undefined;
165
+ if (options.dryRun === true) {
166
+ const where = params.area !== undefined ? "the target area (Anytime)" : "Someday";
167
+ return {
168
+ kind: "dry-run",
169
+ op: "project.create-repeating",
170
+ plan: {
171
+ op: "project.create-repeating",
172
+ vector: "ui",
173
+ tier: 3,
174
+ invocation: `create project "${params.title}" in ${where} (persists on its own) → then make-repeating ` +
175
+ `(select row → Items ▸ Repeat… → frequency=${params.frequency}, interval=${params.interval})`,
176
+ expectedDelta: {
177
+ mode: "create",
178
+ probe: { title: params.title, type: "project", sinceEpoch: 0 },
179
+ assert: [{ field: "repeating.isTemplate", equals: true }],
180
+ },
181
+ hazardsChecked: ["H-UI-DRIVE"],
182
+ },
183
+ };
184
+ }
185
+ const startedAt = deps.now?.() ?? new Date();
186
+ const txnId = newTxnId(startedAt);
187
+ const add = await runMutation(deps, "project.add", {
188
+ title: params.title,
189
+ ...(params.notes !== undefined && { notes: params.notes }),
190
+ ...(params.area !== undefined && { area: params.area }),
191
+ ...(seedWhen !== undefined && { when: seedWhen }),
192
+ ...(params.deadline !== undefined && { deadline: params.deadline }),
193
+ ...(params.todos !== undefined && { todos: params.todos }),
194
+ }, legOptions(options, { id: txnId, role: "leg" }, "url-scheme"));
195
+ if (add.kind !== "ok" || add.uuid === null) {
196
+ return add.kind === "ok"
197
+ ? {
198
+ kind: "verify-failed",
199
+ op: "project.create-repeating",
200
+ reason: "mismatch",
201
+ expected: {
202
+ mode: "create",
203
+ probe: { title: params.title, type: "project", sinceEpoch: 0 },
204
+ assert: [],
205
+ },
206
+ observed: null,
207
+ detail: "the project was created but its uuid was not discovered — cannot promote it to repeating",
208
+ }
209
+ : add;
210
+ }
211
+ const promote = await runMakeRepeatingProject(deps, { uuid: add.uuid, frequency: params.frequency, interval: params.interval }, legOptions(options, { id: txnId, role: "leg" }, "ui"));
212
+ if (promote.kind !== "ok") {
213
+ // Honest: the project was created (and persists) but the promote did not land.
214
+ return promote;
215
+ }
216
+ appendSummary(deps, {
217
+ startedAt,
218
+ uuid: promote.uuid,
219
+ txnId,
220
+ op: "project.create-repeating",
221
+ invocation: `create-repeating project "${params.title}" → template ${promote.uuid ?? "?"}`,
222
+ });
223
+ return { ...promote, op: "project.create-repeating" };
224
+ }
225
+ // --------------------------------------------------------------------- audit
226
+ function appendSummary(deps, args) {
227
+ const fp = deps.fingerprint();
228
+ const record = {
229
+ v: 1,
230
+ ts: args.startedAt.toISOString(),
231
+ actor: deps.config.actor,
232
+ host: deps.config.host,
233
+ op: args.op ?? "project.make-repeating",
234
+ uuid: args.uuid,
235
+ vector: "ui",
236
+ disruption: 3,
237
+ invocation: args.invocation,
238
+ requested: {},
239
+ txn: { id: args.txnId, role: "summary" },
240
+ pre: null,
241
+ observed: args.uuid !== null ? { uuid: args.uuid } : null,
242
+ result: "ok",
243
+ verify: null,
244
+ durationMs: (deps.now?.() ?? new Date()).getTime() - args.startedAt.getTime(),
245
+ env: {
246
+ pkg: deps.pkgVersion ?? "0.0.1",
247
+ dbVersion: fp.observation.databaseVersion,
248
+ fingerprint: fingerprintLabel(fp, deps.config),
249
+ },
250
+ };
251
+ deps.audit.append(record);
252
+ }
253
+ //# sourceMappingURL=make-repeating-project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"make-repeating-project.js","sourceRoot":"","sources":["../../src/write/make-repeating-project.ts"],"names":[],"mappings":"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"}