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
package/dist/client.js ADDED
@@ -0,0 +1,187 @@
1
+ import { createAuditWriter } from "./audit/log.js";
2
+ import { loadConfig } from "./config.js";
3
+ import { PKG_VERSION } from "./contracts.js";
4
+ import { BASELINES } from "./db/baselines/index.js";
5
+ import { openConnection } from "./db/connection.js";
6
+ import { compareToBaseline, observeSchema } from "./db/fingerprint.js";
7
+ import { locateThingsDb } from "./db/locate.js";
8
+ import { auditDir, mutationLockPath } from "./paths.js";
9
+ import { byUuid } from "./read/detail.js";
10
+ import { projectView } from "./read/project-view.js";
11
+ import { snapshotView } from "./read/snapshot.js";
12
+ import { areasView, tagsView } from "./read/tags.js";
13
+ import { anytimeView, changesView, inboxView, logbookView, projectsView, searchView, somedayView, todayView, trashView, upcomingView, } from "./read/views.js";
14
+ import { readAuthToken, runMutation, } from "./write/pipeline.js";
15
+ import { runBatch } from "./write/batch.js";
16
+ import { createEnvironmentTracker } from "./write/environment.js";
17
+ import { runReorder } from "./write/reorder.js";
18
+ import { runUndo } from "./write/undo.js";
19
+ import { runProjectReopen, } from "./write/reopen.js";
20
+ import { defaultVectors } from "./write/vectors/registry.js";
21
+ /** Resolve an item by exact title — loud on missing/ambiguous (never guess). */
22
+ function checklistIndex(items, ref) {
23
+ const matches = items.map((c, i) => ({ c, i })).filter(({ c }) => c.title === ref);
24
+ if (matches.length === 1)
25
+ return matches[0].i;
26
+ throw new RangeError(matches.length === 0
27
+ ? `no checklist item titled "${ref}"`
28
+ : `checklist item title "${ref}" is ambiguous (${matches.length} matches) — rename first`);
29
+ }
30
+ export function applyChecklistEdit(items, edit) {
31
+ const next = items.map((c) => ({ ...c }));
32
+ switch (edit.action) {
33
+ case "add": {
34
+ const at = edit.at === undefined ? next.length : Math.max(0, Math.min(next.length, edit.at - 1));
35
+ next.splice(at, 0, { title: edit.title, completed: false });
36
+ return next;
37
+ }
38
+ case "remove":
39
+ next.splice(checklistIndex(next, edit.item), 1);
40
+ return next;
41
+ case "check":
42
+ case "uncheck": {
43
+ const target = next[checklistIndex(next, edit.item)];
44
+ target.completed = edit.action === "check";
45
+ return next;
46
+ }
47
+ case "rename": {
48
+ const target = next[checklistIndex(next, edit.item)];
49
+ target.title = edit.title;
50
+ return next;
51
+ }
52
+ case "move": {
53
+ const from = checklistIndex(next, edit.item);
54
+ const [moved] = next.splice(from, 1);
55
+ next.splice(Math.max(0, Math.min(next.length, edit.to - 1)), 0, moved);
56
+ return next;
57
+ }
58
+ }
59
+ }
60
+ export function openThings(options = {}) {
61
+ const located = locateThingsDb(options.dbPath ? { dbPath: options.dbPath } : undefined);
62
+ const conn = openConnection(located.path);
63
+ const now = options.now ?? (() => new Date());
64
+ const env = options.env ?? process.env;
65
+ const config = loadConfig(env);
66
+ let cachedStatus = null;
67
+ const fingerprint = () => {
68
+ cachedStatus ??= compareToBaseline(observeSchema(conn.db), BASELINES);
69
+ return cachedStatus;
70
+ };
71
+ const token = readAuthToken(conn.db);
72
+ const audit = options.writeOverrides?.audit ??
73
+ createAuditWriter({
74
+ dir: auditDir(env),
75
+ secrets: token === null ? [] : [token],
76
+ enabled: config.auditEnabled,
77
+ });
78
+ const writeDeps = {
79
+ db: conn.db,
80
+ vectors: options.vectors ?? defaultVectors(),
81
+ config,
82
+ audit,
83
+ fingerprint,
84
+ lockPath: mutationLockPath(env),
85
+ now,
86
+ ...(options.writeOverrides?.ensureRunning !== undefined && {
87
+ ensureRunning: options.writeOverrides.ensureRunning,
88
+ }),
89
+ ...(options.writeOverrides?.isAppRunning !== undefined && {
90
+ isAppRunning: options.writeOverrides.isAppRunning,
91
+ }),
92
+ ...(options.writeOverrides?.poller !== undefined && {
93
+ poller: options.writeOverrides.poller,
94
+ }),
95
+ ...(options.writeOverrides?.sdefProbe !== undefined && {
96
+ sdefProbe: options.writeOverrides.sdefProbe,
97
+ }),
98
+ environment: options.writeOverrides?.environment ?? createEnvironmentTracker(PKG_VERSION, env),
99
+ };
100
+ const run = (op, params, writeOptions) => runMutation(writeDeps, op, params, writeOptions ?? {});
101
+ return {
102
+ dbPath: located.path,
103
+ config,
104
+ fingerprint,
105
+ read: {
106
+ today: (f) => todayView(conn.db, now(), f),
107
+ inbox: (f) => inboxView(conn.db, f),
108
+ anytime: (f) => anytimeView(conn.db, now(), f),
109
+ upcoming: (f) => upcomingView(conn.db, now(), f),
110
+ someday: (f) => somedayView(conn.db, now(), f),
111
+ logbook: (o) => logbookView(conn.db, o),
112
+ trash: (o) => trashView(conn.db, o),
113
+ projects: (o) => projectsView(conn.db, o),
114
+ projectView: (uuid) => projectView(conn.db, uuid, now()),
115
+ areas: () => areasView(conn.db),
116
+ tags: () => tagsView(conn.db),
117
+ search: (query, o) => searchView(conn.db, query, o),
118
+ changes: (o) => changesView(conn.db, o),
119
+ byUuid: (uuid) => byUuid(conn.db, uuid),
120
+ snapshot: () => snapshotView(conn.db),
121
+ },
122
+ write: {
123
+ run,
124
+ addTodo: (params, o) => run("todo.add", params, o),
125
+ updateTodo: (uuid, patch, o) => run("todo.update", { uuid, ...patch }, o),
126
+ completeTodo: (uuid, o) => run("todo.complete", { uuid }, o),
127
+ cancelTodo: (uuid, o) => run("todo.cancel", { uuid }, o),
128
+ reopenTodo: (uuid, o) => run("todo.reopen", { uuid }, o),
129
+ moveTodo: (uuid, dest, o) => run("todo.move", { uuid, ...dest }, o),
130
+ setTags: (uuid, tags, o) => run("todo.set-tags", { uuid, tags }, o),
131
+ addTags(uuid, tags, o) {
132
+ const current = byUuid(conn.db, uuid);
133
+ const existing = current !== null && current.type !== "heading" ? current.tags.map((t) => t.title) : [];
134
+ const merged = [...new Set([...existing, ...tags])];
135
+ return run("todo.set-tags", { uuid, tags: merged }, o);
136
+ },
137
+ replaceChecklist: (uuid, items, o) => run("todo.replace-checklist", { uuid, items }, o),
138
+ deleteTodo: (uuid, o) => run("todo.delete", { uuid }, o),
139
+ duplicateTodo: (uuid, o) => run("todo.duplicate", { uuid }, o),
140
+ restoreTodo: (uuid, o) => run("todo.restore", { uuid }, o),
141
+ backdateTodo: (uuid, dates, o) => run("todo.backdate", { uuid, ...dates }, o),
142
+ addLoggedTodo: (params, o) => run("todo.add-logged", params, o),
143
+ detachTodo: (uuid, o) => run("todo.move", { uuid, detach: true }, o),
144
+ editChecklist(uuid, edit, o) {
145
+ const current = byUuid(conn.db, uuid);
146
+ if (current === null || current.type !== "to-do") {
147
+ throw new RangeError(`no to-do with uuid ${uuid}`);
148
+ }
149
+ const items = (current.checklist ?? []).map((c) => ({
150
+ title: c.title,
151
+ completed: c.status === "completed",
152
+ }));
153
+ const next = applyChecklistEdit(items, edit);
154
+ return run("todo.replace-checklist", { uuid, items: next }, { ...o, acknowledgeChecklistReset: true });
155
+ },
156
+ addProject: (params, o) => run("project.add", params, o),
157
+ updateProject: (uuid, patch, o) => run("project.update", { uuid, ...patch }, o),
158
+ completeProject: (uuid, policy, o) => run("project.complete", { uuid, children: policy.children }, o),
159
+ moveProject: (uuid, area, o) => run("project.move", { uuid, area }, o),
160
+ detachProject: (uuid, o) => run("project.move", { uuid, detach: true }, o),
161
+ cancelProject: (uuid, policy, o) => run("project.cancel", { uuid, children: policy.children }, o),
162
+ reopenProject: (uuid, o) => runProjectReopen(writeDeps, uuid, o ?? {}),
163
+ restoreProject: (uuid, o) => run("project.restore", { uuid }, o),
164
+ duplicateProject: (uuid, o) => run("project.duplicate", { uuid }, o),
165
+ deleteProject: (uuid, o) => run("project.delete", { uuid }, o),
166
+ setProjectTags: (uuid, tags, o) => run("project.set-tags", { uuid, tags }, o),
167
+ addProjectTags(uuid, tags, o) {
168
+ const current = byUuid(conn.db, uuid);
169
+ const existing = current !== null && current.type !== "heading" ? current.tags.map((t) => t.title) : [];
170
+ const merged = [...new Set([...existing, ...tags])];
171
+ return run("project.set-tags", { uuid, tags: merged }, o);
172
+ },
173
+ addArea: (params, o) => run("area.add", params, o),
174
+ updateArea: (target, patch, o) => run("area.update", { target, ...patch }, o),
175
+ deleteArea: (target, o) => run("area.delete", { target }, o),
176
+ addTag: (params, o) => run("tag.add", params, o),
177
+ updateTag: (target, patch, o) => run("tag.update", { target, ...patch }, o),
178
+ deleteTag: (target, o) => run("tag.delete", { target }, o),
179
+ emptyTrash: (o) => run("trash.empty", {}, o),
180
+ reorder: (params, o) => runReorder(writeDeps, params, o ?? {}),
181
+ batch: (ops, o, onResult) => runBatch(writeDeps, ops, o ?? {}, onResult),
182
+ undo: (o, onItem) => runUndo(writeDeps, auditDir(env), o ?? {}, onItem),
183
+ },
184
+ close: () => conn.close(),
185
+ };
186
+ }
187
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ export type Profile = "workstation" | "dedicated-server";
2
+ export type DisruptionTier = 0 | 1 | 2 | 3;
3
+ export interface ThingsApiConfig {
4
+ profile: Profile;
5
+ /** Highest disruption tier allowed without explicit per-call escalation. */
6
+ maxDisruption: DisruptionTier;
7
+ /** Audit attribution when the caller does not pass one. */
8
+ actor: string;
9
+ /** JSONL audit trail on/off (default on). */
10
+ auditEnabled: boolean;
11
+ /** User-accepted drifted fingerprint (loud escape hatch; see design §6). */
12
+ acceptedFingerprint: string | null;
13
+ /**
14
+ * Opt-in to capabilities riding undocumented app surfaces (the private
15
+ * sdef reorder command). Guarded further by the pipeline's sdef canary.
16
+ */
17
+ allowExperimental: boolean;
18
+ host: string;
19
+ }
20
+ interface ConfigFile {
21
+ profile?: Profile;
22
+ maxDisruption?: DisruptionTier;
23
+ actor?: string;
24
+ auditEnabled?: boolean;
25
+ acceptedFingerprint?: string;
26
+ allowExperimental?: boolean;
27
+ }
28
+ export declare function loadConfig(env?: NodeJS.ProcessEnv): ThingsApiConfig;
29
+ /** Persist one config key (CLI `things config set`). */
30
+ export declare function saveConfigKey(key: keyof ConfigFile, value: string | number | boolean | null, env?: NodeJS.ProcessEnv): void;
31
+ export {};
package/dist/config.js ADDED
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Config profiles + env overrides.
3
+ *
4
+ * `workstation` (default): a human may be at the screen — background app
5
+ * launch (tier 1) is acceptable, focus steal (tier 2) requires an explicit
6
+ * flag. `dedicated-server`: nobody is watching; tier 2 allowed by default.
7
+ */
8
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
9
+ import { hostname, userInfo } from "node:os";
10
+ import { join } from "node:path";
11
+ import { configDir } from "./paths.js";
12
+ const PROFILE_DEFAULT_TIER = {
13
+ workstation: 1,
14
+ "dedicated-server": 2,
15
+ };
16
+ function configFilePath(env) {
17
+ return join(configDir(env), "config.json");
18
+ }
19
+ export function loadConfig(env = process.env) {
20
+ let file = {};
21
+ const path = configFilePath(env);
22
+ if (existsSync(path)) {
23
+ try {
24
+ file = JSON.parse(readFileSync(path, "utf8"));
25
+ }
26
+ catch {
27
+ // Malformed config falls back to defaults; doctor reports it.
28
+ }
29
+ }
30
+ const profile = env["THINGS_API_PROFILE"] === "dedicated-server" || file.profile === "dedicated-server"
31
+ ? "dedicated-server"
32
+ : "workstation";
33
+ const envTier = env["THINGS_API_MAX_DISRUPTION"];
34
+ const maxDisruption = (envTier !== undefined && /^[0-3]$/.test(envTier)
35
+ ? Number(envTier)
36
+ : (file.maxDisruption ?? PROFILE_DEFAULT_TIER[profile]));
37
+ let username = "unknown";
38
+ try {
39
+ username = userInfo().username;
40
+ }
41
+ catch {
42
+ // leave "unknown"
43
+ }
44
+ return {
45
+ profile,
46
+ maxDisruption,
47
+ actor: env["THINGS_API_ACTOR"] ?? file.actor ?? `${username}@cli`,
48
+ auditEnabled: env["THINGS_API_AUDIT"] === "off" ? false : (file.auditEnabled ?? true),
49
+ acceptedFingerprint: file.acceptedFingerprint ?? null,
50
+ allowExperimental: env["THINGS_API_ALLOW_EXPERIMENTAL"] === "true" || file.allowExperimental === true,
51
+ host: hostname(),
52
+ };
53
+ }
54
+ /** Persist one config key (CLI `things config set`). */
55
+ export function saveConfigKey(key, value, env = process.env) {
56
+ const dir = configDir(env);
57
+ mkdirSync(dir, { recursive: true });
58
+ const path = configFilePath(env);
59
+ let file = {};
60
+ if (existsSync(path)) {
61
+ try {
62
+ file = JSON.parse(readFileSync(path, "utf8"));
63
+ }
64
+ catch {
65
+ file = {};
66
+ }
67
+ }
68
+ if (value === null) {
69
+ delete file[key];
70
+ }
71
+ else {
72
+ file[key] = value;
73
+ }
74
+ writeFileSync(path, `${JSON.stringify(file, null, 2)}\n`);
75
+ }
76
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAuBvC,MAAM,oBAAoB,GAAoC;IAC5D,WAAW,EAAE,CAAC;IACd,kBAAkB,EAAE,CAAC;CACtB,CAAC;AAWF,SAAS,cAAc,CAAC,GAAsB;IAC5C,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,aAAa,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAyB,OAAO,CAAC,GAAG;IAC7D,IAAI,IAAI,GAAe,EAAE,CAAC;IAC1B,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACrB,IAAI,CAAC;YACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAe,CAAC;QAC9D,CAAC;QAAC,MAAM,CAAC;YACP,8DAA8D;QAChE,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GACX,GAAG,CAAC,oBAAoB,CAAC,KAAK,kBAAkB,IAAI,IAAI,CAAC,OAAO,KAAK,kBAAkB;QACrF,CAAC,CAAC,kBAAkB;QACpB,CAAC,CAAC,aAAa,CAAC;IAEpB,MAAM,OAAO,GAAG,GAAG,CAAC,2BAA2B,CAAC,CAAC;IACjD,MAAM,aAAa,GAAG,CACpB,OAAO,KAAK,SAAS,IAAI,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC;QAC9C,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;QACjB,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,IAAI,oBAAoB,CAAC,OAAO,CAAC,CAAC,CACxC,CAAC;IAEpB,IAAI,QAAQ,GAAG,SAAS,CAAC;IACzB,IAAI,CAAC;QACH,QAAQ,GAAG,QAAQ,EAAE,CAAC,QAAQ,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,kBAAkB;IACpB,CAAC;IAED,OAAO;QACL,OAAO;QACP,aAAa;QACb,KAAK,EAAE,GAAG,CAAC,kBAAkB,CAAC,IAAI,IAAI,CAAC,KAAK,IAAI,GAAG,QAAQ,MAAM;QACjE,YAAY,EAAE,GAAG,CAAC,kBAAkB,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC;QACrF,mBAAmB,EAAE,IAAI,CAAC,mBAAmB,IAAI,IAAI;QACrD,iBAAiB,EACf,GAAG,CAAC,+BAA+B,CAAC,KAAK,MAAM,IAAI,IAAI,CAAC,iBAAiB,KAAK,IAAI;QACpF,IAAI,EAAE,QAAQ,EAAE;KACjB,CAAC;AACJ,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,aAAa,CAC3B,GAAqB,EACrB,KAAuC,EACvC,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IAC3B,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,IAAI,GAAe,EAAE,CAAC;IAC1B,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACrB,IAAI,CAAC;YACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAe,CAAC;QAC9D,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,GAAG,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IACD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;SAAM,CAAC;QACL,IAAgC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACjD,CAAC;IACD,aAAa,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AAC5D,CAAC"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Machine-facing contracts shared by every surface over the library (CLI
3
+ * --json envelopes, MCP tool results): the versioned envelope shape and the
4
+ * stable exit-code family. Lives in the CORE so thin surfaces depend on the
5
+ * library, never on each other (see docs/design/contracts.md).
6
+ *
7
+ * - Envelope JSON goes to stdout; all human/log chatter goes to stderr.
8
+ * - `apiVersion` is bumped only on breaking envelope-shape changes.
9
+ * - `data` is command-specific; `error` is present exactly when `ok` is false.
10
+ */
11
+ export declare const API_VERSION = 1;
12
+ /**
13
+ * Package version, surfaced by `things --version` and the MCP serverInfo.
14
+ * Kept in lockstep with package.json by a contract test.
15
+ */
16
+ export declare const PKG_VERSION = "0.5.0";
17
+ /**
18
+ * Stable exit-code contract for the `things` CLI (mirrored by MCP error
19
+ * codes). Part of the public API surface consumed by agents and scripts —
20
+ * values must never be renumbered; add new codes at the end.
21
+ */
22
+ export declare const ExitCode: {
23
+ /** Success. */
24
+ readonly Ok: 0;
25
+ /** Unexpected internal error (bug, unhandled condition). */
26
+ readonly Unexpected: 1;
27
+ /** Usage error: unknown command, bad flags, invalid arguments. */
28
+ readonly Usage: 2;
29
+ /** Mutation executed but read-after-write verification failed (timeout, mismatch, or silent no-op). */
30
+ readonly VerifyFailed: 3;
31
+ /** Mutation refused before touching the app: hazard guard or disruption-tier policy. */
32
+ readonly Blocked: 4;
33
+ /** Writes disabled because the database schema fingerprint deviates from the known baseline. */
34
+ readonly DriftBlocked: 5;
35
+ /** Operation not supported by any available write vector. */
36
+ readonly Unsupported: 6;
37
+ /** Environment problem: database not found, Things not installed, permissions. */
38
+ readonly Environment: 7;
39
+ };
40
+ export type ExitCode = (typeof ExitCode)[keyof typeof ExitCode];
41
+ export interface EnvelopeMeta {
42
+ /** Things database schema version (`Meta.databaseVersion`), null when no DB was opened. */
43
+ dbVersion: number | null;
44
+ /** Schema fingerprint status at the time of the command. */
45
+ fingerprint: "ok" | "drift" | "user-accepted" | "unknown";
46
+ /** Wall-clock duration of the command in milliseconds. */
47
+ elapsedMs: number;
48
+ }
49
+ export interface OkEnvelope<T> {
50
+ apiVersion: typeof API_VERSION;
51
+ ok: true;
52
+ /** Discriminator naming the payload shape, e.g. "today", "mutation-result". */
53
+ kind: string;
54
+ data: T;
55
+ meta: EnvelopeMeta;
56
+ }
57
+ export interface ErrorEnvelope {
58
+ apiVersion: typeof API_VERSION;
59
+ ok: false;
60
+ kind: "error";
61
+ error: {
62
+ /** Stable machine-readable code, mirrors the exit-code family (e.g. "verify-failed", "blocked"). */
63
+ code: string;
64
+ message: string;
65
+ /**
66
+ * Advisory attribution when failure signals point somewhere: e.g.
67
+ * "permission-denied", "permission-pending", "feature-disabled",
68
+ * "app-updated", "schema-drift", "app-behavior-change".
69
+ */
70
+ likelyCause?: string;
71
+ /** Actionable next step for the caller, when one exists. */
72
+ remediation?: string;
73
+ detail?: unknown;
74
+ };
75
+ meta: EnvelopeMeta;
76
+ }
77
+ export type Envelope<T> = OkEnvelope<T> | ErrorEnvelope;
78
+ export declare function okEnvelope<T>(kind: string, data: T, meta: EnvelopeMeta): OkEnvelope<T>;
79
+ export declare function errorEnvelope(error: ErrorEnvelope["error"], meta: EnvelopeMeta): ErrorEnvelope;
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Machine-facing contracts shared by every surface over the library (CLI
3
+ * --json envelopes, MCP tool results): the versioned envelope shape and the
4
+ * stable exit-code family. Lives in the CORE so thin surfaces depend on the
5
+ * library, never on each other (see docs/design/contracts.md).
6
+ *
7
+ * - Envelope JSON goes to stdout; all human/log chatter goes to stderr.
8
+ * - `apiVersion` is bumped only on breaking envelope-shape changes.
9
+ * - `data` is command-specific; `error` is present exactly when `ok` is false.
10
+ */
11
+ export const API_VERSION = 1;
12
+ /**
13
+ * Package version, surfaced by `things --version` and the MCP serverInfo.
14
+ * Kept in lockstep with package.json by a contract test.
15
+ */
16
+ export const PKG_VERSION = "0.5.0";
17
+ /**
18
+ * Stable exit-code contract for the `things` CLI (mirrored by MCP error
19
+ * codes). Part of the public API surface consumed by agents and scripts —
20
+ * values must never be renumbered; add new codes at the end.
21
+ */
22
+ export const ExitCode = {
23
+ /** Success. */
24
+ Ok: 0,
25
+ /** Unexpected internal error (bug, unhandled condition). */
26
+ Unexpected: 1,
27
+ /** Usage error: unknown command, bad flags, invalid arguments. */
28
+ Usage: 2,
29
+ /** Mutation executed but read-after-write verification failed (timeout, mismatch, or silent no-op). */
30
+ VerifyFailed: 3,
31
+ /** Mutation refused before touching the app: hazard guard or disruption-tier policy. */
32
+ Blocked: 4,
33
+ /** Writes disabled because the database schema fingerprint deviates from the known baseline. */
34
+ DriftBlocked: 5,
35
+ /** Operation not supported by any available write vector. */
36
+ Unsupported: 6,
37
+ /** Environment problem: database not found, Things not installed, permissions. */
38
+ Environment: 7,
39
+ };
40
+ export function okEnvelope(kind, data, meta) {
41
+ return { apiVersion: API_VERSION, ok: true, kind, data, meta };
42
+ }
43
+ export function errorEnvelope(error, meta) {
44
+ return { apiVersion: API_VERSION, ok: false, kind: "error", error, meta };
45
+ }
46
+ //# sourceMappingURL=contracts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contracts.js","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC;AAE7B;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC;AAEnC;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,eAAe;IACf,EAAE,EAAE,CAAC;IACL,4DAA4D;IAC5D,UAAU,EAAE,CAAC;IACb,kEAAkE;IAClE,KAAK,EAAE,CAAC;IACR,uGAAuG;IACvG,YAAY,EAAE,CAAC;IACf,wFAAwF;IACxF,OAAO,EAAE,CAAC;IACV,gGAAgG;IAChG,YAAY,EAAE,CAAC;IACf,6DAA6D;IAC7D,WAAW,EAAE,CAAC;IACd,kFAAkF;IAClF,WAAW,EAAE,CAAC;CACN,CAAC;AA6CX,MAAM,UAAU,UAAU,CAAI,IAAY,EAAE,IAAO,EAAE,IAAkB;IACrE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAA6B,EAAE,IAAkB;IAC7E,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AAC5E,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { Baseline } from "../fingerprint.ts";
2
+ /**
3
+ * Schema baseline for Meta.databaseVersion = 26.
4
+ * Captured 2026-07-02 from a live Things 3.22.11 library; the fixture DDL
5
+ * (test/fixtures/schema-v26.sql) reproduces this fingerprint exactly
6
+ * (asserted by test/unit/fingerprint.test.ts).
7
+ */
8
+ export declare const DB_V26: Baseline;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Schema baseline for Meta.databaseVersion = 26.
3
+ * Captured 2026-07-02 from a live Things 3.22.11 library; the fixture DDL
4
+ * (test/fixtures/schema-v26.sql) reproduces this fingerprint exactly
5
+ * (asserted by test/unit/fingerprint.test.ts).
6
+ */
7
+ export const DB_V26 = {
8
+ databaseVersion: 26,
9
+ // Recomputed 2026-07-04 (Phase 10b/10c): manifest gained
10
+ // rt1_instanceCreationPaused (occurrence synthesis) and
11
+ // deadlineSuppressionDate (deadline-driven Today membership); verified
12
+ // identical from the live library and the fixture DDL.
13
+ fingerprint: "sha256:5526059b10ffffe1b67f796d031857d030403bd5b747374646a2803a55c0e5c3",
14
+ knownThingsAppVersions: ["3.22.11"],
15
+ };
16
+ //# sourceMappingURL=db-v26.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-v26.js","sourceRoot":"","sources":["../../../src/db/baselines/db-v26.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,MAAM,GAAa;IAC9B,eAAe,EAAE,EAAE;IACnB,yDAAyD;IACzD,wDAAwD;IACxD,uEAAuE;IACvE,uDAAuD;IACvD,WAAW,EAAE,yEAAyE;IACtF,sBAAsB,EAAE,CAAC,SAAS,CAAC;CACpC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Baseline } from "../fingerprint.ts";
2
+ /** All known-good schema baselines, keyed by Meta.databaseVersion. */
3
+ export declare const BASELINES: readonly Baseline[];
@@ -0,0 +1,4 @@
1
+ import { DB_V26 } from "./db-v26.js";
2
+ /** All known-good schema baselines, keyed by Meta.databaseVersion. */
3
+ export const BASELINES = [DB_V26];
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/db/baselines/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,sEAAsE;AACtE,MAAM,CAAC,MAAM,SAAS,GAAwB,CAAC,MAAM,CAAC,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Read-only connection to a Things database via node:sqlite.
3
+ *
4
+ * WAL policy (docs/design/architecture.md §0):
5
+ * - `readOnly: true`, never `immutable=1` — the DB changes while Things runs;
6
+ * immutable would poison verification polling with stale snapshots.
7
+ * - Each statement outside a transaction gets a fresh WAL read snapshot;
8
+ * the verification poller relies on this. Never wrap polling in a
9
+ * long-lived transaction.
10
+ * - Requires the -shm/-wal sidecars to be accessible (present whenever
11
+ * Things has run at least once).
12
+ */
13
+ import { DatabaseSync } from "node:sqlite";
14
+ export interface ThingsConnection {
15
+ db: DatabaseSync;
16
+ path: string;
17
+ close(): void;
18
+ }
19
+ export declare class ThingsDbOpenError extends Error {
20
+ constructor(path: string, cause: unknown);
21
+ }
22
+ export declare function openConnection(path: string): ThingsConnection;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Read-only connection to a Things database via node:sqlite.
3
+ *
4
+ * WAL policy (docs/design/architecture.md §0):
5
+ * - `readOnly: true`, never `immutable=1` — the DB changes while Things runs;
6
+ * immutable would poison verification polling with stale snapshots.
7
+ * - Each statement outside a transaction gets a fresh WAL read snapshot;
8
+ * the verification poller relies on this. Never wrap polling in a
9
+ * long-lived transaction.
10
+ * - Requires the -shm/-wal sidecars to be accessible (present whenever
11
+ * Things has run at least once).
12
+ */
13
+ import { DatabaseSync } from "node:sqlite";
14
+ export class ThingsDbOpenError extends Error {
15
+ constructor(path, cause) {
16
+ super(`Could not open Things database read-only at ${path}. ` +
17
+ `If this is a WAL/-shm access error, launch Things once and retry.`, { cause });
18
+ this.name = "ThingsDbOpenError";
19
+ }
20
+ }
21
+ export function openConnection(path) {
22
+ let db;
23
+ try {
24
+ db = new DatabaseSync(path, {
25
+ readOnly: true,
26
+ timeout: 2000,
27
+ });
28
+ }
29
+ catch (cause) {
30
+ throw new ThingsDbOpenError(path, cause);
31
+ }
32
+ return {
33
+ db,
34
+ path,
35
+ close() {
36
+ db.close();
37
+ },
38
+ };
39
+ }
40
+ //# sourceMappingURL=connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/db/connection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAQ3C,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAC1C,YAAY,IAAY,EAAE,KAAc;QACtC,KAAK,CACH,+CAA+C,IAAI,IAAI;YACrD,mEAAmE,EACrE,EAAE,KAAK,EAAE,CACV,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF;AAED,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,IAAI,EAAgB,CAAC;IACrB,IAAI,CAAC;QACH,EAAE,GAAG,IAAI,YAAY,CAAC,IAAI,EAAE;YAC1B,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,iBAAiB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO;QACL,EAAE;QACF,IAAI;QACJ,KAAK;YACH,EAAE,CAAC,KAAK,EAAE,CAAC;QACb,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,42 @@
1
+ import type { DatabaseSync } from "node:sqlite";
2
+ import { type DependedTable } from "./schema.ts";
3
+ export interface ColumnShape {
4
+ name: string;
5
+ declaredType: string;
6
+ notnull: 0 | 1;
7
+ pk: number;
8
+ }
9
+ export interface TableShape {
10
+ table: DependedTable;
11
+ present: boolean;
12
+ /** Depended columns in manifest order; absent ones recorded as null. */
13
+ columns: Array<ColumnShape | null>;
14
+ /** Columns present in the DB but not in the manifest (informational). */
15
+ extraColumns: string[];
16
+ }
17
+ export interface SchemaObservation {
18
+ databaseVersion: number | null;
19
+ tables: TableShape[];
20
+ fingerprint: string;
21
+ }
22
+ export declare function observeSchema(db: DatabaseSync): SchemaObservation;
23
+ /** Meta.databaseVersion is a plist blob/text wrapping an <integer>. */
24
+ export declare function readDatabaseVersion(db: DatabaseSync): number | null;
25
+ export type FingerprintStatus = {
26
+ kind: "ok";
27
+ observation: SchemaObservation;
28
+ } | {
29
+ kind: "drift";
30
+ observation: SchemaObservation;
31
+ expected: string;
32
+ detail: string[];
33
+ } | {
34
+ kind: "unknown-version";
35
+ observation: SchemaObservation;
36
+ };
37
+ export interface Baseline {
38
+ databaseVersion: number;
39
+ fingerprint: string;
40
+ knownThingsAppVersions: string[];
41
+ }
42
+ export declare function compareToBaseline(observation: SchemaObservation, baselines: readonly Baseline[]): FingerprintStatus;