things-api 0.5.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 (184) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +77 -0
  3. package/bin/things.js +9 -0
  4. package/dist/audit/log.d.ts +10 -0
  5. package/dist/audit/log.js +31 -0
  6. package/dist/audit/log.js.map +1 -0
  7. package/dist/audit/schema.d.ts +37 -0
  8. package/dist/audit/schema.js +9 -0
  9. package/dist/audit/schema.js.map +1 -0
  10. package/dist/cli/commands/doctor.d.ts +9 -0
  11. package/dist/cli/commands/doctor.js +60 -0
  12. package/dist/cli/commands/doctor.js.map +1 -0
  13. package/dist/cli/commands/mcp.d.ts +7 -0
  14. package/dist/cli/commands/mcp.js +26 -0
  15. package/dist/cli/commands/mcp.js.map +1 -0
  16. package/dist/cli/commands/project.d.ts +5 -0
  17. package/dist/cli/commands/project.js +50 -0
  18. package/dist/cli/commands/project.js.map +1 -0
  19. package/dist/cli/commands/reads.d.ts +21 -0
  20. package/dist/cli/commands/reads.js +295 -0
  21. package/dist/cli/commands/reads.js.map +1 -0
  22. package/dist/cli/commands/snapshot.d.ts +7 -0
  23. package/dist/cli/commands/snapshot.js +22 -0
  24. package/dist/cli/commands/snapshot.js.map +1 -0
  25. package/dist/cli/commands/todo.d.ts +6 -0
  26. package/dist/cli/commands/todo.js +43 -0
  27. package/dist/cli/commands/todo.js.map +1 -0
  28. package/dist/cli/commands/writes.d.ts +9 -0
  29. package/dist/cli/commands/writes.js +994 -0
  30. package/dist/cli/commands/writes.js.map +1 -0
  31. package/dist/cli/exit-codes.d.ts +26 -0
  32. package/dist/cli/exit-codes.js +26 -0
  33. package/dist/cli/exit-codes.js.map +1 -0
  34. package/dist/cli/main.d.ts +4 -0
  35. package/dist/cli/main.js +73 -0
  36. package/dist/cli/main.js.map +1 -0
  37. package/dist/cli/output.d.ts +42 -0
  38. package/dist/cli/output.js +16 -0
  39. package/dist/cli/output.js.map +1 -0
  40. package/dist/cli/style.d.ts +6 -0
  41. package/dist/cli/style.js +25 -0
  42. package/dist/cli/style.js.map +1 -0
  43. package/dist/client.d.ts +184 -0
  44. package/dist/client.js +187 -0
  45. package/dist/client.js.map +1 -0
  46. package/dist/config.d.ts +31 -0
  47. package/dist/config.js +76 -0
  48. package/dist/config.js.map +1 -0
  49. package/dist/contracts.d.ts +79 -0
  50. package/dist/contracts.js +46 -0
  51. package/dist/contracts.js.map +1 -0
  52. package/dist/db/baselines/db-v26.d.ts +8 -0
  53. package/dist/db/baselines/db-v26.js +16 -0
  54. package/dist/db/baselines/db-v26.js.map +1 -0
  55. package/dist/db/baselines/index.d.ts +3 -0
  56. package/dist/db/baselines/index.js +4 -0
  57. package/dist/db/baselines/index.js.map +1 -0
  58. package/dist/db/connection.d.ts +22 -0
  59. package/dist/db/connection.js +40 -0
  60. package/dist/db/connection.js.map +1 -0
  61. package/dist/db/fingerprint.d.ts +42 -0
  62. package/dist/db/fingerprint.js +82 -0
  63. package/dist/db/fingerprint.js.map +1 -0
  64. package/dist/db/locate.d.ts +13 -0
  65. package/dist/db/locate.js +44 -0
  66. package/dist/db/locate.js.map +1 -0
  67. package/dist/db/schema.d.ts +37 -0
  68. package/dist/db/schema.js +81 -0
  69. package/dist/db/schema.js.map +1 -0
  70. package/dist/diagnose.d.ts +67 -0
  71. package/dist/diagnose.js +143 -0
  72. package/dist/diagnose.js.map +1 -0
  73. package/dist/index.d.ts +46 -0
  74. package/dist/index.js +23 -0
  75. package/dist/index.js.map +1 -0
  76. package/dist/mcp/server.d.ts +8 -0
  77. package/dist/mcp/server.js +1002 -0
  78. package/dist/mcp/server.js.map +1 -0
  79. package/dist/model/dates.d.ts +38 -0
  80. package/dist/model/dates.js +104 -0
  81. package/dist/model/dates.js.map +1 -0
  82. package/dist/model/entities.d.ts +117 -0
  83. package/dist/model/entities.js +21 -0
  84. package/dist/model/entities.js.map +1 -0
  85. package/dist/model/mappers.d.ts +55 -0
  86. package/dist/model/mappers.js +105 -0
  87. package/dist/model/mappers.js.map +1 -0
  88. package/dist/model/occurrences.d.ts +46 -0
  89. package/dist/model/occurrences.js +164 -0
  90. package/dist/model/occurrences.js.map +1 -0
  91. package/dist/model/recurrence.d.ts +52 -0
  92. package/dist/model/recurrence.js +164 -0
  93. package/dist/model/recurrence.js.map +1 -0
  94. package/dist/paths.d.ts +6 -0
  95. package/dist/paths.js +30 -0
  96. package/dist/paths.js.map +1 -0
  97. package/dist/read/detail.d.ts +8 -0
  98. package/dist/read/detail.js +34 -0
  99. package/dist/read/detail.js.map +1 -0
  100. package/dist/read/project-view.d.ts +34 -0
  101. package/dist/read/project-view.js +87 -0
  102. package/dist/read/project-view.js.map +1 -0
  103. package/dist/read/queries.d.ts +39 -0
  104. package/dist/read/queries.js +134 -0
  105. package/dist/read/queries.js.map +1 -0
  106. package/dist/read/snapshot.d.ts +25 -0
  107. package/dist/read/snapshot.js +39 -0
  108. package/dist/read/snapshot.js.map +1 -0
  109. package/dist/read/tags.d.ts +17 -0
  110. package/dist/read/tags.js +64 -0
  111. package/dist/read/tags.js.map +1 -0
  112. package/dist/read/views.d.ts +152 -0
  113. package/dist/read/views.js +322 -0
  114. package/dist/read/views.js.map +1 -0
  115. package/dist/surface-copy.d.ts +15 -0
  116. package/dist/surface-copy.js +16 -0
  117. package/dist/surface-copy.js.map +1 -0
  118. package/dist/write/automation-probe.d.ts +12 -0
  119. package/dist/write/automation-probe.js +59 -0
  120. package/dist/write/automation-probe.js.map +1 -0
  121. package/dist/write/batch.d.ts +51 -0
  122. package/dist/write/batch.js +97 -0
  123. package/dist/write/batch.js.map +1 -0
  124. package/dist/write/capabilities.d.ts +16 -0
  125. package/dist/write/capabilities.js +16 -0
  126. package/dist/write/capabilities.js.map +1 -0
  127. package/dist/write/commands.d.ts +32 -0
  128. package/dist/write/commands.js +1274 -0
  129. package/dist/write/commands.js.map +1 -0
  130. package/dist/write/environment.d.ts +29 -0
  131. package/dist/write/environment.js +105 -0
  132. package/dist/write/environment.js.map +1 -0
  133. package/dist/write/experimental.d.ts +7 -0
  134. package/dist/write/experimental.js +39 -0
  135. package/dist/write/experimental.js.map +1 -0
  136. package/dist/write/failure-hints.d.ts +32 -0
  137. package/dist/write/failure-hints.js +71 -0
  138. package/dist/write/failure-hints.js.map +1 -0
  139. package/dist/write/guards.d.ts +21 -0
  140. package/dist/write/guards.js +312 -0
  141. package/dist/write/guards.js.map +1 -0
  142. package/dist/write/lock.d.ts +10 -0
  143. package/dist/write/lock.js +70 -0
  144. package/dist/write/lock.js.map +1 -0
  145. package/dist/write/operations.d.ts +262 -0
  146. package/dist/write/operations.js +34 -0
  147. package/dist/write/operations.js.map +1 -0
  148. package/dist/write/pipeline.d.ts +90 -0
  149. package/dist/write/pipeline.js +375 -0
  150. package/dist/write/pipeline.js.map +1 -0
  151. package/dist/write/planner.d.ts +40 -0
  152. package/dist/write/planner.js +57 -0
  153. package/dist/write/planner.js.map +1 -0
  154. package/dist/write/pre-state.d.ts +125 -0
  155. package/dist/write/pre-state.js +299 -0
  156. package/dist/write/pre-state.js.map +1 -0
  157. package/dist/write/reopen.d.ts +29 -0
  158. package/dist/write/reopen.js +63 -0
  159. package/dist/write/reopen.js.map +1 -0
  160. package/dist/write/reorder.d.ts +19 -0
  161. package/dist/write/reorder.js +285 -0
  162. package/dist/write/reorder.js.map +1 -0
  163. package/dist/write/undo.d.ts +53 -0
  164. package/dist/write/undo.js +703 -0
  165. package/dist/write/undo.js.map +1 -0
  166. package/dist/write/vectors/applescript.d.ts +5 -0
  167. package/dist/write/vectors/applescript.js +216 -0
  168. package/dist/write/vectors/applescript.js.map +1 -0
  169. package/dist/write/vectors/registry.d.ts +2 -0
  170. package/dist/write/vectors/registry.js +11 -0
  171. package/dist/write/vectors/registry.js.map +1 -0
  172. package/dist/write/vectors/types.d.ts +48 -0
  173. package/dist/write/vectors/types.js +2 -0
  174. package/dist/write/vectors/types.js.map +1 -0
  175. package/dist/write/vectors/url-scheme.d.ts +3 -0
  176. package/dist/write/vectors/url-scheme.js +176 -0
  177. package/dist/write/vectors/url-scheme.js.map +1 -0
  178. package/dist/write/verify/delta.d.ts +126 -0
  179. package/dist/write/verify/delta.js +281 -0
  180. package/dist/write/verify/delta.js.map +1 -0
  181. package/dist/write/verify/poller.d.ts +24 -0
  182. package/dist/write/verify/poller.js +28 -0
  183. package/dist/write/verify/poller.js.map +1 -0
  184. package/package.json +52 -0
@@ -0,0 +1,285 @@
1
+ import { localToday, encodePackedDate } from "../model/dates.js";
2
+ import { computeReorderPre, resolveArea, resolveProject } from "./pre-state.js";
3
+ import { sdefDeclaresPrivateReorder } from "./experimental.js";
4
+ import { fingerprintLabel, runMutation, } from "./pipeline.js";
5
+ import { createDbReader, evaluateDelta } from "./verify/delta.js";
6
+ import { pollUntilVerified } from "./verify/poller.js";
7
+ /**
8
+ * Bounce cost is 2 verified mutations per item; beyond this the today scope
9
+ * should use the native strategy and the evening scope should be re-thought.
10
+ */
11
+ export const BOUNCE_MAX_ITEMS = 10;
12
+ export async function runReorder(deps, params, options = {}) {
13
+ const strategy = resolveStrategy(deps, params);
14
+ if (strategy.kind === "blocked")
15
+ return strategy.result;
16
+ if (strategy.strategy === "native") {
17
+ return runMutation(deps, "reorder", params, { ...options, vector: "applescript" });
18
+ }
19
+ return runBounce(deps, params, options);
20
+ }
21
+ function resolveStrategy(deps, params) {
22
+ const blocked = (detail, remediation) => ({
23
+ kind: "blocked",
24
+ result: {
25
+ kind: "blocked",
26
+ op: "reorder",
27
+ reason: "hazard",
28
+ hazard: "H-REORDER-SCOPE",
29
+ detail,
30
+ remediation,
31
+ },
32
+ });
33
+ const nativeAvailable = deps.config.allowExperimental && (deps.sdefProbe ?? sdefDeclaresPrivateReorder)();
34
+ if (params.strategy === "native") {
35
+ if (params.scope === "evening") {
36
+ return blocked("evening reorder is bounce-only: the native command silently clears startBucket on " +
37
+ "every listed item (O03)", "omit --strategy (evening defaults to bounce)");
38
+ }
39
+ if (params.scope === "projects") {
40
+ return blocked("top-level sidebar order has NO native surface (every AppleScript spelling errors " +
41
+ "and the private command no-ops — scf2 P6); only the when= bounce works (P8e)", "omit --strategy (projects defaults to bounce)");
42
+ }
43
+ return { kind: "ok", strategy: "native" };
44
+ }
45
+ if (params.strategy === "bounce") {
46
+ if (params.scope === "project" ||
47
+ params.scope === "area" ||
48
+ params.scope === "inbox" ||
49
+ params.scope === "headings" ||
50
+ params.scope === "someday") {
51
+ return blocked("bounce can only reorder the Today/Evening sections and top-level projects — its " +
52
+ "primitive is a when= round-trip, which does not move this scope's order", "use the native strategy (requires `things config set allow-experimental true`)");
53
+ }
54
+ return { kind: "ok", strategy: "bounce" };
55
+ }
56
+ // Default per scope.
57
+ switch (params.scope) {
58
+ case "evening":
59
+ case "projects":
60
+ return { kind: "ok", strategy: "bounce" };
61
+ case "today":
62
+ return { kind: "ok", strategy: nativeAvailable ? "native" : "bounce" };
63
+ case "project":
64
+ case "area":
65
+ case "inbox":
66
+ case "headings":
67
+ case "someday":
68
+ // Native-only scopes: let the pipeline explain precisely why native is
69
+ // unavailable (planner: experimental gate; canary: sdef change).
70
+ return { kind: "ok", strategy: "native" };
71
+ }
72
+ }
73
+ // ------------------------------------------------------------------- bounce
74
+ async function runBounce(deps, params, options) {
75
+ const startedAt = deps.now?.() ?? new Date();
76
+ const now = deps.now ?? (() => new Date());
77
+ const scope = params.scope;
78
+ const rankKey = scope === "projects" ? "index" : "todayIndex";
79
+ const legOp = scope === "projects" ? "project.update" : "todo.update";
80
+ // Scope/membership guard — same data the native path's guard uses.
81
+ const pre = computeReorderPre(deps.db, params, resolveContainerUuid(deps, params), now());
82
+ const problems = [];
83
+ if (params.container !== undefined)
84
+ problems.push("container is only valid for project/area/headings scopes");
85
+ if (params.uuids.length === 0)
86
+ problems.push("no uuids given");
87
+ if (pre.duplicates.length > 0)
88
+ problems.push(`duplicated uuid(s): ${pre.duplicates.join(", ")}`);
89
+ for (const r of pre.rejected)
90
+ problems.push(`${r.uuid} ${r.reason}`);
91
+ if (scope !== "projects") {
92
+ for (const uuid of pre.projectMembers) {
93
+ problems.push(`${uuid} is a project — bounce re-schedules via todo.update, which is only validated ` +
94
+ "for to-dos; use the native strategy for Today lists containing projects");
95
+ }
96
+ }
97
+ if (params.uuids.length > BOUNCE_MAX_ITEMS) {
98
+ problems.push(`${params.uuids.length} items exceeds the bounce cap of ${BOUNCE_MAX_ITEMS} ` +
99
+ "(each item costs two verified mutations)");
100
+ }
101
+ if (problems.length > 0) {
102
+ const result = {
103
+ kind: "blocked",
104
+ op: "reorder",
105
+ reason: "hazard",
106
+ hazard: "H-REORDER-SCOPE",
107
+ detail: `reorder request rejected: ${problems.join("; ")}`,
108
+ remediation: "read the scope first (things today) and pass only its eligible members, " +
109
+ `at most ${BOUNCE_MAX_ITEMS} for the bounce strategy`,
110
+ };
111
+ auditSummary(deps, params, startedAt, "blocked:H-REORDER-SCOPE", null);
112
+ return result;
113
+ }
114
+ const away = scope === "today" ? "evening" : scope === "projects" ? "someday" : "today";
115
+ const back = scope === "projects" ? "anytime" : scope;
116
+ if (options.dryRun === true) {
117
+ return {
118
+ kind: "dry-run",
119
+ op: "reorder",
120
+ plan: {
121
+ op: "reorder",
122
+ vector: "url-scheme",
123
+ tier: 0,
124
+ invocation: `bounce ×${params.uuids.length} (reverse order): ` +
125
+ `when=${away} → verified → when=${back} → verified; ` +
126
+ "state re-checked between items",
127
+ expectedDelta: { mode: "ordering", key: rankKey, sequence: params.uuids },
128
+ hazardsChecked: ["H-REORDER-SCOPE"],
129
+ },
130
+ };
131
+ }
132
+ // Bounce in REVERSE: each round-trip front-inserts (O07/O08), so placing
133
+ // the last item first leaves the requested order on top.
134
+ const placed = [];
135
+ for (let i = params.uuids.length - 1; i >= 0; i--) {
136
+ const uuid = params.uuids[i];
137
+ // Concurrent-edit re-check: the item must still be an eligible member.
138
+ const memberProblem = checkStillMember(deps, uuid, scope, now());
139
+ if (memberProblem !== null) {
140
+ const detail = `aborted before bouncing ${uuid}: ${memberProblem} (Things was likely edited ` +
141
+ "concurrently); already-placed items keep their new positions";
142
+ auditSummary(deps, params, startedAt, "verify-failed:mismatch", { placed: [...placed] });
143
+ return {
144
+ kind: "bounce-aborted",
145
+ op: "reorder",
146
+ detail,
147
+ placed: [...placed],
148
+ remaining: params.uuids.slice(0, i + 1),
149
+ cause: null,
150
+ };
151
+ }
152
+ const leg1 = await runMutation(deps, legOp, { uuid, when: away }, legOptions(options));
153
+ if (leg1.kind !== "ok") {
154
+ auditSummary(deps, params, startedAt, "verify-failed:mismatch", { placed: [...placed] });
155
+ return {
156
+ kind: "bounce-aborted",
157
+ op: "reorder",
158
+ detail: `bounce leg 1 (when=${away}) failed for ${uuid} — the item was NOT moved`,
159
+ placed: [...placed],
160
+ remaining: params.uuids.slice(0, i + 1),
161
+ cause: leg1,
162
+ };
163
+ }
164
+ const leg2 = await runMutation(deps, legOp, { uuid, when: back }, legOptions(options));
165
+ if (leg2.kind !== "ok") {
166
+ auditSummary(deps, params, startedAt, "verify-failed:mismatch", { placed: [...placed] });
167
+ return {
168
+ kind: "bounce-aborted",
169
+ op: "reorder",
170
+ detail: `bounce leg 2 (when=${back}) failed for ${uuid} — THE ITEM IS STRANDED IN ` +
171
+ `${away.toUpperCase()}; re-schedule it (when=${back}) or fix in the app`,
172
+ placed: [...placed],
173
+ remaining: params.uuids.slice(0, i + 1),
174
+ cause: leg2,
175
+ };
176
+ }
177
+ placed.unshift(uuid);
178
+ // Placed-prefix invariant: everything bounced so far must read back in
179
+ // requested relative order — anything else means a concurrent reshuffle.
180
+ const prefixCheck = await pollUntilVerified(() => evaluateDelta({ mode: "ordering", key: rankKey, sequence: [...placed] }, createDbReader(deps.db), { modDates: {}, fields: {} }), options.verifyTimeoutMs ?? 4000, deps.poller ?? {});
181
+ if (prefixCheck.kind !== "ok") {
182
+ auditSummary(deps, params, startedAt, "verify-failed:mismatch", { placed: [...placed] });
183
+ return {
184
+ kind: "bounce-aborted",
185
+ op: "reorder",
186
+ detail: `placed items fell out of order after bouncing ${uuid} (concurrent edit?); ` +
187
+ "re-run the reorder once Things is idle",
188
+ placed: [...placed],
189
+ remaining: params.uuids.slice(0, i),
190
+ cause: null,
191
+ };
192
+ }
193
+ }
194
+ const reader = createDbReader(deps.db);
195
+ const observed = {};
196
+ for (const uuid of params.uuids)
197
+ observed[uuid] = reader.rankOf(uuid, rankKey);
198
+ auditSummary(deps, params, startedAt, "ok", observed);
199
+ return {
200
+ kind: "ok",
201
+ op: "reorder",
202
+ uuid: null,
203
+ observed,
204
+ vector: "url-scheme",
205
+ tier: 0,
206
+ };
207
+ }
208
+ function legOptions(options) {
209
+ const legs = {};
210
+ if (options.maxDisruption !== undefined)
211
+ legs.maxDisruption = options.maxDisruption;
212
+ if (options.verifyTimeoutMs !== undefined)
213
+ legs.verifyTimeoutMs = options.verifyTimeoutMs;
214
+ if (options.actor !== undefined)
215
+ legs.actor = options.actor;
216
+ return legs;
217
+ }
218
+ function resolveContainerUuid(deps, params) {
219
+ if (params.scope === "project" || params.scope === "headings") {
220
+ return resolveProject(deps.db, params.container ?? {}).resolved?.uuid ?? null;
221
+ }
222
+ if (params.scope === "area") {
223
+ return resolveArea(deps.db, params.container ?? {}).resolved?.uuid ?? null;
224
+ }
225
+ return null;
226
+ }
227
+ /** null = still eligible; otherwise a human-readable problem. */
228
+ function checkStillMember(deps, uuid, scope, now) {
229
+ const packedToday = encodePackedDate(localToday(now));
230
+ const row = deps.db
231
+ .prepare("SELECT status, trashed, startBucket, startDate, start, type, area FROM TMTask WHERE uuid = ?")
232
+ .get(uuid);
233
+ if (row === undefined)
234
+ return "the item no longer exists";
235
+ if (row.trashed !== 0)
236
+ return "the item was trashed";
237
+ if (row.status !== 0)
238
+ return "the item is no longer open";
239
+ if (scope === "projects") {
240
+ if (row.type !== 1)
241
+ return "the item is not a project";
242
+ if (row.area !== null)
243
+ return "the project moved into an area";
244
+ if (row.start !== 1 || row.startDate !== null) {
245
+ return "the project is no longer a plain Anytime project";
246
+ }
247
+ return null;
248
+ }
249
+ const inToday = row.startDate !== null && row.startDate <= packedToday && (row.start === 1 || row.start === 2);
250
+ if (!inToday)
251
+ return "the item left the Today list";
252
+ if (scope === "today" && row.startBucket !== 0)
253
+ return "the item moved to This Evening";
254
+ if (scope === "evening" && (row.startBucket !== 1 || row.startDate !== packedToday)) {
255
+ return "the item left This Evening";
256
+ }
257
+ return null;
258
+ }
259
+ function auditSummary(deps, params, startedAt, result, observed) {
260
+ const fp = deps.fingerprint();
261
+ const record = {
262
+ v: 1,
263
+ ts: startedAt.toISOString(),
264
+ actor: deps.config.actor,
265
+ host: deps.config.host,
266
+ op: "reorder",
267
+ uuid: null,
268
+ vector: "url-scheme",
269
+ disruption: 0,
270
+ invocation: `bounce(${params.scope}) ×${params.uuids.length}`,
271
+ requested: params,
272
+ pre: null,
273
+ observed,
274
+ result,
275
+ verify: null,
276
+ durationMs: (deps.now?.() ?? new Date()).getTime() - startedAt.getTime(),
277
+ env: {
278
+ pkg: deps.pkgVersion ?? "0.0.1",
279
+ dbVersion: fp.observation.databaseVersion,
280
+ fingerprint: fingerprintLabel(fp, deps.config),
281
+ },
282
+ };
283
+ deps.audit.append(record);
284
+ }
285
+ //# sourceMappingURL=reorder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reorder.js","sourceRoot":"","sources":["../../src/write/reorder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import type { AuditRecord } from "../audit/schema.ts";
2
+ import type { OperationKind } from "./operations.ts";
3
+ import { type MutationResult, type WriteDeps } from "./pipeline.ts";
4
+ import { type ReorderResult } from "./reorder.ts";
5
+ export interface UndoStep {
6
+ op: OperationKind;
7
+ params: Record<string, unknown>;
8
+ /** Acknowledgements the inverse op needs (surfaced in the plan). */
9
+ options?: {
10
+ acknowledgeChecklistReset?: boolean;
11
+ dangerouslyPermanent?: boolean;
12
+ };
13
+ }
14
+ export interface UndoPlan {
15
+ /** The audit record being undone. */
16
+ target: {
17
+ ts: string;
18
+ op: string;
19
+ uuid: string | null;
20
+ actor: string;
21
+ };
22
+ kind: "invertible" | "irreversible";
23
+ steps: UndoStep[];
24
+ /** Fidelity caveats — what the inverse cannot restore. */
25
+ notes: string[];
26
+ /** Present when kind is "irreversible". */
27
+ reason?: string;
28
+ }
29
+ export interface UndoItemResult {
30
+ plan: UndoPlan;
31
+ /** One result per executed step (empty for dry-run/irreversible). */
32
+ results: (MutationResult | ReorderResult)[];
33
+ outcome: "ok" | "partial" | "failed" | "irreversible" | "dry-run";
34
+ }
35
+ export interface UndoOptions {
36
+ /** How many trailing mutations to undo (default 1). */
37
+ last?: number;
38
+ dryRun?: boolean;
39
+ /** Required for inverses that delete areas/tags permanently. */
40
+ dangerouslyPermanent?: boolean;
41
+ verifyTimeoutMs?: number;
42
+ actor?: string;
43
+ }
44
+ /** Parse every audit record from the monthly JSONL files, oldest first. */
45
+ export declare function readAuditRecords(dir: string): AuditRecord[];
46
+ /**
47
+ * The last N undoable targets, NEWEST FIRST (undo unwinds a stack). Only
48
+ * successful mutations qualify; inverse mutations (actor `undo:…`) never do.
49
+ */
50
+ export declare function selectUndoTargets(records: AuditRecord[], last: number): AuditRecord[];
51
+ /** Build the inverse plan for one audit record. Pure — unit-testable. */
52
+ export declare function planUndo(record: AuditRecord, now: Date): UndoPlan;
53
+ export declare function runUndo(deps: WriteDeps, auditDirPath: string, options?: UndoOptions, onItem?: (item: UndoItemResult) => void): Promise<UndoItemResult[]>;