things-api 0.17.0 → 0.19.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 (277) hide show
  1. package/README.md +16 -9
  2. package/deputy/AppIcon.icns +0 -0
  3. package/deputy/VERSION +1 -0
  4. package/deputy/helpers-Info.plist +27 -0
  5. package/deputy/prebuilt/Things API Helper.app/Contents/CodeResources +0 -0
  6. package/deputy/prebuilt/Things API Helper.app/Contents/Helpers/things-reader.app/Contents/Info.plist +22 -0
  7. package/deputy/prebuilt/Things API Helper.app/Contents/Helpers/things-reader.app/Contents/MacOS/things-reader +0 -0
  8. package/deputy/prebuilt/Things API Helper.app/Contents/Helpers/things-reader.app/Contents/Resources/AppIcon.icns +0 -0
  9. package/deputy/prebuilt/Things API Helper.app/Contents/Helpers/things-reader.app/Contents/_CodeSignature/CodeResources +128 -0
  10. package/deputy/prebuilt/Things API Helper.app/Contents/Info.plist +27 -0
  11. package/deputy/prebuilt/Things API Helper.app/Contents/MacOS/things-deputy +0 -0
  12. package/deputy/prebuilt/Things API Helper.app/Contents/Resources/AppIcon.icns +0 -0
  13. package/deputy/prebuilt/Things API Helper.app/Contents/_CodeSignature/CodeResources +137 -0
  14. package/deputy/reader/Info.plist +22 -0
  15. package/deputy/reader/entitlements.plist +45 -0
  16. package/deputy/reader/main.swift +580 -0
  17. package/deputy/src/main.swift +133 -0
  18. package/deputy/src/osascript.swift +102 -0
  19. package/deputy/src/server.swift +373 -0
  20. package/deputy/src/sqlite.swift +121 -0
  21. package/deputy/src/tcc.swift +58 -0
  22. package/dist/audit/schema.d.ts +13 -1
  23. package/dist/audit/schema.js.map +1 -1
  24. package/dist/capability.d.ts +160 -0
  25. package/dist/capability.js +416 -0
  26. package/dist/capability.js.map +1 -0
  27. package/dist/cli/commands/doctor.js +181 -2
  28. package/dist/cli/commands/doctor.js.map +1 -1
  29. package/dist/cli/commands/helpers.d.ts +17 -0
  30. package/dist/cli/commands/helpers.js +275 -0
  31. package/dist/cli/commands/helpers.js.map +1 -0
  32. package/dist/cli/commands/op-result.d.ts +15 -0
  33. package/dist/cli/commands/op-result.js +45 -0
  34. package/dist/cli/commands/op-result.js.map +1 -0
  35. package/dist/cli/commands/reads.js +47 -1
  36. package/dist/cli/commands/reads.js.map +1 -1
  37. package/dist/cli/commands/setup.d.ts +9 -0
  38. package/dist/cli/commands/setup.js +63 -83
  39. package/dist/cli/commands/setup.js.map +1 -1
  40. package/dist/cli/commands/writes.d.ts +1 -1
  41. package/dist/cli/commands/writes.js +262 -109
  42. package/dist/cli/commands/writes.js.map +1 -1
  43. package/dist/cli/dry-run.d.ts +1 -1
  44. package/dist/cli/dry-run.js +1 -1
  45. package/dist/cli/glyphs.d.ts +23 -4
  46. package/dist/cli/glyphs.js +46 -19
  47. package/dist/cli/glyphs.js.map +1 -1
  48. package/dist/cli/help.d.ts +1 -1
  49. package/dist/cli/help.js +53 -27
  50. package/dist/cli/help.js.map +1 -1
  51. package/dist/cli/helpers-check.d.ts +10 -0
  52. package/dist/cli/helpers-check.js +59 -0
  53. package/dist/cli/helpers-check.js.map +1 -0
  54. package/dist/cli/main.js +22 -1
  55. package/dist/cli/main.js.map +1 -1
  56. package/dist/cli/period.d.ts +3 -1
  57. package/dist/cli/period.js +1 -1
  58. package/dist/cli/period.js.map +1 -1
  59. package/dist/cli/read-driver.js +26 -1
  60. package/dist/cli/read-driver.js.map +1 -1
  61. package/dist/cli/render.d.ts +31 -4
  62. package/dist/cli/render.js +127 -15
  63. package/dist/cli/render.js.map +1 -1
  64. package/dist/client.d.ts +22 -2
  65. package/dist/client.js +52 -15
  66. package/dist/client.js.map +1 -1
  67. package/dist/config.d.ts +31 -0
  68. package/dist/config.js +9 -0
  69. package/dist/config.js.map +1 -1
  70. package/dist/contracts.d.ts +6 -2
  71. package/dist/contracts.js +1 -1
  72. package/dist/contracts.js.map +1 -1
  73. package/dist/db/baselines/db-v26.js +8 -4
  74. package/dist/db/baselines/db-v26.js.map +1 -1
  75. package/dist/db/baselines/db-v27.d.ts +42 -0
  76. package/dist/db/baselines/db-v27.js +47 -0
  77. package/dist/db/baselines/db-v27.js.map +1 -0
  78. package/dist/db/baselines/index.js +2 -1
  79. package/dist/db/baselines/index.js.map +1 -1
  80. package/dist/db/locate.d.ts +4 -1
  81. package/dist/db/locate.js +3 -1
  82. package/dist/db/locate.js.map +1 -1
  83. package/dist/db/schema.d.ts +1 -1
  84. package/dist/db/schema.js +9 -0
  85. package/dist/db/schema.js.map +1 -1
  86. package/dist/deputy/bridge-worker.d.ts +1 -0
  87. package/dist/deputy/bridge-worker.js +79 -0
  88. package/dist/deputy/bridge-worker.js.map +1 -0
  89. package/dist/deputy/bridge.d.ts +14 -0
  90. package/dist/deputy/bridge.js +70 -0
  91. package/dist/deputy/bridge.js.map +1 -0
  92. package/dist/deputy/client.d.ts +19 -0
  93. package/dist/deputy/client.js +104 -0
  94. package/dist/deputy/client.js.map +1 -0
  95. package/dist/deputy/db-facade.d.ts +18 -0
  96. package/dist/deputy/db-facade.js +71 -0
  97. package/dist/deputy/db-facade.js.map +1 -0
  98. package/dist/deputy/files.d.ts +1 -0
  99. package/dist/deputy/files.js +16 -0
  100. package/dist/deputy/files.js.map +1 -0
  101. package/dist/deputy/install.d.ts +319 -0
  102. package/dist/deputy/install.js +1239 -0
  103. package/dist/deputy/install.js.map +1 -0
  104. package/dist/deputy/notice.d.ts +6 -0
  105. package/dist/deputy/notice.js +28 -0
  106. package/dist/deputy/notice.js.map +1 -0
  107. package/dist/deputy/notices.d.ts +31 -0
  108. package/dist/deputy/notices.js +94 -0
  109. package/dist/deputy/notices.js.map +1 -0
  110. package/dist/deputy/osa.d.ts +21 -0
  111. package/dist/deputy/osa.js +72 -0
  112. package/dist/deputy/osa.js.map +1 -0
  113. package/dist/deputy/protocol.d.ts +140 -0
  114. package/dist/deputy/protocol.js +143 -0
  115. package/dist/deputy/protocol.js.map +1 -0
  116. package/dist/deputy/routing.d.ts +84 -0
  117. package/dist/deputy/routing.js +422 -0
  118. package/dist/deputy/routing.js.map +1 -0
  119. package/dist/deputy/shortcuts-exec.d.ts +10 -0
  120. package/dist/deputy/shortcuts-exec.js +50 -0
  121. package/dist/deputy/shortcuts-exec.js.map +1 -0
  122. package/dist/diagnose.d.ts +57 -2
  123. package/dist/diagnose.js +105 -3
  124. package/dist/diagnose.js.map +1 -1
  125. package/dist/direct-setup.d.ts +78 -0
  126. package/dist/direct-setup.js +484 -0
  127. package/dist/direct-setup.js.map +1 -0
  128. package/dist/host-access.d.ts +63 -0
  129. package/dist/host-access.js +165 -0
  130. package/dist/host-access.js.map +1 -0
  131. package/dist/index.d.ts +31 -5
  132. package/dist/index.js +23 -1
  133. package/dist/index.js.map +1 -1
  134. package/dist/mcp/server.d.ts +27 -1
  135. package/dist/mcp/server.js +300 -97
  136. package/dist/mcp/server.js.map +1 -1
  137. package/dist/model/mappers.d.ts +12 -3
  138. package/dist/model/mappers.js +6 -1
  139. package/dist/model/mappers.js.map +1 -1
  140. package/dist/model/recurrence.d.ts +5 -1
  141. package/dist/model/recurrence.js +19 -1
  142. package/dist/model/recurrence.js.map +1 -1
  143. package/dist/model/template-projection.d.ts +26 -0
  144. package/dist/model/template-projection.js +113 -0
  145. package/dist/model/template-projection.js.map +1 -0
  146. package/dist/op-result.d.ts +55 -0
  147. package/dist/op-result.js +161 -0
  148. package/dist/op-result.js.map +1 -0
  149. package/dist/read/detail.js +7 -1
  150. package/dist/read/detail.js.map +1 -1
  151. package/dist/read/filter-contract.d.ts +1 -1
  152. package/dist/read/filter-contract.js +4 -0
  153. package/dist/read/filter-contract.js.map +1 -1
  154. package/dist/read/queries.js +8 -1
  155. package/dist/read/queries.js.map +1 -1
  156. package/dist/read/shape.js +4 -0
  157. package/dist/read/shape.js.map +1 -1
  158. package/dist/read/views.d.ts +35 -4
  159. package/dist/read/views.js +120 -18
  160. package/dist/read/views.js.map +1 -1
  161. package/dist/session-grant.d.ts +48 -0
  162. package/dist/session-grant.js +170 -0
  163. package/dist/session-grant.js.map +1 -0
  164. package/dist/surface-copy.d.ts +8 -0
  165. package/dist/surface-copy.js +8 -0
  166. package/dist/surface-copy.js.map +1 -1
  167. package/dist/sync-health.js +6 -2
  168. package/dist/sync-health.js.map +1 -1
  169. package/dist/wizard.d.ts +58 -0
  170. package/dist/wizard.js +167 -0
  171. package/dist/wizard.js.map +1 -0
  172. package/dist/write/accessibility-probe.js +4 -2
  173. package/dist/write/accessibility-probe.js.map +1 -1
  174. package/dist/write/automation-probe.js +5 -1
  175. package/dist/write/automation-probe.js.map +1 -1
  176. package/dist/write/availability.d.ts +1 -1
  177. package/dist/write/availability.js +10 -6
  178. package/dist/write/availability.js.map +1 -1
  179. package/dist/write/batch.d.ts +20 -0
  180. package/dist/write/batch.js +94 -15
  181. package/dist/write/batch.js.map +1 -1
  182. package/dist/write/capabilities.d.ts +9 -0
  183. package/dist/write/capabilities.js +2 -0
  184. package/dist/write/capabilities.js.map +1 -1
  185. package/dist/write/clear-reminder.js +1 -1
  186. package/dist/write/clear-reminder.js.map +1 -1
  187. package/dist/write/commands.d.ts +12 -1
  188. package/dist/write/commands.js +170 -237
  189. package/dist/write/commands.js.map +1 -1
  190. package/dist/write/experimental.d.ts +19 -0
  191. package/dist/write/experimental.js +50 -0
  192. package/dist/write/experimental.js.map +1 -1
  193. package/dist/write/failure-hints.d.ts +3 -1
  194. package/dist/write/failure-hints.js.map +1 -1
  195. package/dist/write/guards.js +19 -2
  196. package/dist/write/guards.js.map +1 -1
  197. package/dist/write/lock.d.ts +16 -13
  198. package/dist/write/lock.js +55 -0
  199. package/dist/write/lock.js.map +1 -1
  200. package/dist/write/make-repeating-project.js +9 -13
  201. package/dist/write/make-repeating-project.js.map +1 -1
  202. package/dist/write/move.js +14 -6
  203. package/dist/write/move.js.map +1 -1
  204. package/dist/write/operations.d.ts +64 -25
  205. package/dist/write/operations.js +7 -0
  206. package/dist/write/operations.js.map +1 -1
  207. package/dist/write/opid.d.ts +14 -0
  208. package/dist/write/opid.js +22 -0
  209. package/dist/write/opid.js.map +1 -1
  210. package/dist/write/param-schema.d.ts +124 -0
  211. package/dist/write/param-schema.js +747 -0
  212. package/dist/write/param-schema.js.map +1 -0
  213. package/dist/write/pipeline.d.ts +78 -2
  214. package/dist/write/pipeline.js +249 -4
  215. package/dist/write/pipeline.js.map +1 -1
  216. package/dist/write/pre-state.d.ts +8 -0
  217. package/dist/write/pre-state.js +62 -17
  218. package/dist/write/pre-state.js.map +1 -1
  219. package/dist/write/promote-clone.js +635 -367
  220. package/dist/write/promote-clone.js.map +1 -1
  221. package/dist/write/reorder.js +95 -29
  222. package/dist/write/reorder.js.map +1 -1
  223. package/dist/write/repeat-anchor.d.ts +30 -0
  224. package/dist/write/repeat-anchor.js +166 -1
  225. package/dist/write/repeat-anchor.js.map +1 -1
  226. package/dist/write/repeat-rule.d.ts +28 -1
  227. package/dist/write/repeat-rule.js +64 -4
  228. package/dist/write/repeat-rule.js.map +1 -1
  229. package/dist/write/resolution-timestamps.d.ts +11 -0
  230. package/dist/write/resolution-timestamps.js +83 -38
  231. package/dist/write/resolution-timestamps.js.map +1 -1
  232. package/dist/write/reversibility.js +4 -0
  233. package/dist/write/reversibility.js.map +1 -1
  234. package/dist/write/template-mutation.d.ts +137 -0
  235. package/dist/write/template-mutation.js +451 -0
  236. package/dist/write/template-mutation.js.map +1 -0
  237. package/dist/write/undo.js +10 -20
  238. package/dist/write/undo.js.map +1 -1
  239. package/dist/write/update-fields.d.ts +151 -0
  240. package/dist/write/update-fields.js +427 -0
  241. package/dist/write/update-fields.js.map +1 -0
  242. package/dist/write/vectors/applescript.js +10 -16
  243. package/dist/write/vectors/applescript.js.map +1 -1
  244. package/dist/write/vectors/registry.d.ts +1 -1
  245. package/dist/write/vectors/registry.js +10 -2
  246. package/dist/write/vectors/registry.js.map +1 -1
  247. package/dist/write/vectors/session-reachability.d.ts +55 -0
  248. package/dist/write/vectors/session-reachability.js +56 -8
  249. package/dist/write/vectors/session-reachability.js.map +1 -1
  250. package/dist/write/vectors/shortcuts.js +7 -16
  251. package/dist/write/vectors/shortcuts.js.map +1 -1
  252. package/dist/write/vectors/simulator.d.ts +16 -1
  253. package/dist/write/vectors/simulator.js +68 -12
  254. package/dist/write/vectors/simulator.js.map +1 -1
  255. package/dist/write/vectors/types.d.ts +124 -1
  256. package/dist/write/vectors/ui-recipes.d.ts +19 -0
  257. package/dist/write/vectors/ui-recipes.js +158 -38
  258. package/dist/write/vectors/ui-recipes.js.map +1 -1
  259. package/dist/write/vectors/ui.d.ts +89 -0
  260. package/dist/write/vectors/ui.js +504 -49
  261. package/dist/write/vectors/ui.js.map +1 -1
  262. package/dist/write/verify/delta.d.ts +21 -0
  263. package/dist/write/verify/delta.js.map +1 -1
  264. package/dist/write/verify/poller.d.ts +13 -0
  265. package/dist/write/verify/poller.js +38 -0
  266. package/dist/write/verify/poller.js.map +1 -1
  267. package/package.json +9 -1
  268. package/schema/envelope.schema.json +5 -3
  269. package/scripts/build-helpers.sh +109 -0
  270. package/scripts/deputy-cert-setup.sh +60 -0
  271. package/skills/things-cli/SKILL.md +12 -5
  272. package/skills/things-cli/references/contracts.md +1 -0
  273. package/skills/things-cli/references/data-model.md +3 -0
  274. package/skills/things-cli/references/errors.md +5 -1
  275. package/skills/things-cli/references/gui.md +1 -0
  276. package/skills/things-cli/references/repeating.md +75 -0
  277. package/skills/things-cli/references/tag-cleanup.md +64 -0
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Worker half of the synchronous deputy bridge (see bridge.ts). Owns the
3
+ * long-lived socket to the deputy and services one request at a time: the main
4
+ * thread posts a request on the message port and blocks in Atomics.wait; this
5
+ * worker performs the socket round-trip, posts the response back, and bumps the
6
+ * shared counter to wake the main thread.
7
+ */
8
+ import { connect } from "node:net";
9
+ import { workerData } from "node:worker_threads";
10
+ const { socketPath, sab, port } = workerData;
11
+ const flag = new Int32Array(sab);
12
+ let socket = null;
13
+ let buffer = "";
14
+ let pendingLine = null;
15
+ let pendingError = null;
16
+ function resetSocket(err) {
17
+ socket = null;
18
+ buffer = "";
19
+ const reject = pendingError;
20
+ pendingLine = null;
21
+ pendingError = null;
22
+ reject?.(err);
23
+ }
24
+ function ensureSocket() {
25
+ if (socket !== null)
26
+ return Promise.resolve(socket);
27
+ return new Promise((resolve, reject) => {
28
+ const sock = connect(socketPath);
29
+ sock.setEncoding("utf8");
30
+ sock.once("connect", () => {
31
+ socket = sock;
32
+ resolve(sock);
33
+ });
34
+ sock.on("data", (chunk) => {
35
+ buffer += chunk;
36
+ const nl = buffer.indexOf("\n");
37
+ if (nl < 0)
38
+ return;
39
+ const line = buffer.slice(0, nl);
40
+ buffer = buffer.slice(nl + 1);
41
+ const deliver = pendingLine;
42
+ pendingLine = null;
43
+ pendingError = null;
44
+ deliver?.(line);
45
+ });
46
+ sock.on("error", (err) => {
47
+ if (socket === null)
48
+ reject(err);
49
+ resetSocket(err);
50
+ });
51
+ sock.on("close", () => {
52
+ resetSocket(new Error("deputy closed the connection"));
53
+ });
54
+ });
55
+ }
56
+ async function roundTrip(request) {
57
+ const sock = await ensureSocket();
58
+ const line = await new Promise((resolve, reject) => {
59
+ pendingLine = resolve;
60
+ pendingError = reject;
61
+ sock.write(`${JSON.stringify(request)}\n`);
62
+ });
63
+ return JSON.parse(line);
64
+ }
65
+ port.on("message", ({ bridgeId, request }) => {
66
+ void roundTrip(request)
67
+ .then((response) => ({ bridgeId, response: response }))
68
+ .catch((err) => ({
69
+ bridgeId,
70
+ error: err instanceof Error ? err.message : String(err),
71
+ }))
72
+ .then((envelope) => {
73
+ port.postMessage(envelope);
74
+ Atomics.add(flag, 0, 1);
75
+ Atomics.notify(flag, 0);
76
+ });
77
+ });
78
+ port.start();
79
+ //# sourceMappingURL=bridge-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge-worker.js","sourceRoot":"","sources":["../../src/deputy/bridge-worker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export declare class DeputySyncBridge {
2
+ private readonly worker;
3
+ private readonly flag;
4
+ private readonly port;
5
+ private seq;
6
+ constructor(socketPath: string);
7
+ /**
8
+ * Send one request and block until its response (or the deadline). Late
9
+ * responses from a previously timed-out request are drained and discarded by
10
+ * the id match, so one timeout never poisons the next call.
11
+ */
12
+ request(payload: Record<string, unknown>, timeoutMs: number): Record<string, unknown>;
13
+ close(): void;
14
+ }
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Synchronous bridge to the deputy for callers that cannot await — the
3
+ * DatabaseSync-shaped read facade and the sync consent probes. A dedicated
4
+ * worker thread owns the socket; the main thread posts a request, blocks in
5
+ * Atomics.wait on a shared counter, then drains the port with
6
+ * receiveMessageOnPort. One request is in flight at a time by construction
7
+ * (the main thread is blocked while it waits).
8
+ *
9
+ * The bridge must NOT be used for long-running osascript drives — blocking the
10
+ * event loop would suspend the drive watchdog and signal handlers. Async
11
+ * dispatch rides client.ts instead.
12
+ */
13
+ import { MessageChannel, receiveMessageOnPort, Worker, } from "node:worker_threads";
14
+ import { DeputyRequestError } from "./protocol.js";
15
+ export class DeputySyncBridge {
16
+ worker;
17
+ flag;
18
+ port;
19
+ seq = 0;
20
+ constructor(socketPath) {
21
+ const sab = new SharedArrayBuffer(4);
22
+ this.flag = new Int32Array(sab);
23
+ const channel = new MessageChannel();
24
+ this.port = channel.port1;
25
+ // Live TS source runs the .ts twin; the published build runs the emitted
26
+ // .js next to this module (same trick as src/cli/version.ts).
27
+ const ext = import.meta.url.endsWith(".ts") ? "ts" : "js";
28
+ this.worker = new Worker(new URL(`./bridge-worker.${ext}`, import.meta.url), {
29
+ workerData: { socketPath, sab, port: channel.port2 },
30
+ transferList: [channel.port2],
31
+ });
32
+ // The bridge must never keep the CLI process alive on its own.
33
+ this.worker.unref();
34
+ }
35
+ /**
36
+ * Send one request and block until its response (or the deadline). Late
37
+ * responses from a previously timed-out request are drained and discarded by
38
+ * the id match, so one timeout never poisons the next call.
39
+ */
40
+ request(payload, timeoutMs) {
41
+ const id = `s${++this.seq}`;
42
+ let seen = Atomics.load(this.flag, 0);
43
+ // oxlint-disable-next-line require-post-message-target-origin -- worker_threads port, no targetOrigin
44
+ this.port.postMessage({ bridgeId: id, request: payload });
45
+ const deadline = Date.now() + timeoutMs;
46
+ for (;;) {
47
+ let received = receiveMessageOnPort(this.port);
48
+ while (received !== undefined) {
49
+ const message = received.message;
50
+ if (message.bridgeId === id) {
51
+ if (message.error !== undefined) {
52
+ throw new DeputyRequestError("bridge-io", message.error);
53
+ }
54
+ return message.response ?? {};
55
+ }
56
+ received = receiveMessageOnPort(this.port);
57
+ }
58
+ const remaining = deadline - Date.now();
59
+ if (remaining <= 0) {
60
+ throw new DeputyRequestError("bridge-timeout", `the deputy did not answer within ${timeoutMs}ms`);
61
+ }
62
+ Atomics.wait(this.flag, 0, seen, remaining);
63
+ seen = Atomics.load(this.flag, 0);
64
+ }
65
+ }
66
+ close() {
67
+ void this.worker.terminate();
68
+ }
69
+ }
70
+ //# sourceMappingURL=bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.js","sourceRoot":"","sources":["../../src/deputy/bridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ export declare class DeputyAsyncClient {
2
+ private socket;
3
+ private buffer;
4
+ private seq;
5
+ private readonly pending;
6
+ private readonly socketPath;
7
+ constructor(socketPath: string);
8
+ private ensureSocket;
9
+ private onData;
10
+ private failAll;
11
+ /**
12
+ * Send one request; resolves with the raw response object (protocol errors
13
+ * included — the caller inspects `ok`). Rejects only on transport failure or
14
+ * client-side deadline (`timeoutMs` should exceed any deputy-side timeout so
15
+ * the deputy's own honest answer wins).
16
+ */
17
+ request(payload: Record<string, unknown>, timeoutMs: number): Promise<Record<string, unknown>>;
18
+ close(): void;
19
+ }
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Async deputy client for event-loop-friendly callers: the applescript vector
3
+ * and the ui vector's step runner. Long osascript drives ride this client so
4
+ * timers (drive watchdog) and signal handlers keep running; synchronous
5
+ * callers ride bridge.ts instead. One shared socket, requests matched by id.
6
+ */
7
+ import { connect } from "node:net";
8
+ import { DeputyRequestError } from "./protocol.js";
9
+ export class DeputyAsyncClient {
10
+ socket = null;
11
+ buffer = "";
12
+ seq = 0;
13
+ pending = new Map();
14
+ socketPath;
15
+ constructor(socketPath) {
16
+ this.socketPath = socketPath;
17
+ }
18
+ ensureSocket() {
19
+ if (this.socket !== null)
20
+ return Promise.resolve(this.socket);
21
+ return new Promise((resolve, reject) => {
22
+ const sock = connect(this.socketPath);
23
+ sock.setEncoding("utf8");
24
+ sock.once("connect", () => {
25
+ this.socket = sock;
26
+ // An idle deputy connection must never keep the CLI process alive.
27
+ sock.unref();
28
+ resolve(sock);
29
+ });
30
+ sock.on("data", (chunk) => this.onData(chunk));
31
+ sock.on("error", (err) => {
32
+ if (this.socket === null)
33
+ reject(err);
34
+ this.failAll(err);
35
+ });
36
+ sock.on("close", () => this.failAll(new Error("deputy closed the connection")));
37
+ });
38
+ }
39
+ onData(chunk) {
40
+ this.buffer += chunk;
41
+ for (;;) {
42
+ const nl = this.buffer.indexOf("\n");
43
+ if (nl < 0)
44
+ return;
45
+ const line = this.buffer.slice(0, nl);
46
+ this.buffer = this.buffer.slice(nl + 1);
47
+ let parsed;
48
+ try {
49
+ parsed = JSON.parse(line);
50
+ }
51
+ catch {
52
+ continue;
53
+ }
54
+ const id = typeof parsed["id"] === "string" ? parsed["id"] : null;
55
+ const entry = id !== null ? this.pending.get(id) : undefined;
56
+ if (id === null || entry === undefined)
57
+ continue;
58
+ this.pending.delete(id);
59
+ clearTimeout(entry.timer);
60
+ entry.resolve(parsed);
61
+ }
62
+ }
63
+ failAll(err) {
64
+ this.socket = null;
65
+ this.buffer = "";
66
+ const waiting = [...this.pending.values()];
67
+ this.pending.clear();
68
+ for (const entry of waiting) {
69
+ clearTimeout(entry.timer);
70
+ entry.reject(err);
71
+ }
72
+ }
73
+ /**
74
+ * Send one request; resolves with the raw response object (protocol errors
75
+ * included — the caller inspects `ok`). Rejects only on transport failure or
76
+ * client-side deadline (`timeoutMs` should exceed any deputy-side timeout so
77
+ * the deputy's own honest answer wins).
78
+ */
79
+ async request(payload, timeoutMs) {
80
+ const sock = await this.ensureSocket();
81
+ const id = `a${++this.seq}`;
82
+ // Wake the socket handle while a request is in flight (see unref above).
83
+ sock.ref();
84
+ try {
85
+ return await new Promise((resolve, reject) => {
86
+ const timer = setTimeout(() => {
87
+ this.pending.delete(id);
88
+ reject(new DeputyRequestError("client-timeout", `the deputy did not answer within ${timeoutMs}ms`));
89
+ }, timeoutMs);
90
+ this.pending.set(id, { resolve, reject, timer });
91
+ sock.write(`${JSON.stringify({ ...payload, id })}\n`);
92
+ });
93
+ }
94
+ finally {
95
+ if (this.pending.size === 0)
96
+ sock.unref();
97
+ }
98
+ }
99
+ close() {
100
+ this.socket?.destroy();
101
+ this.socket = null;
102
+ }
103
+ }
104
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/deputy/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * A DatabaseSync-shaped READ facade over the deputy's `sql` verb. The read
3
+ * layer types against node:sqlite's DatabaseSync and only ever prepares
4
+ * SELECT/PRAGMA statements consumed via `.all()` / `.get()`; this facade
5
+ * implements exactly that surface synchronously (through the bridge) and
6
+ * throws a teaching error on anything else — never a silent no-op. WAL
7
+ * freshness is preserved: the deputy holds one read-only connection outside
8
+ * any transaction, so every statement sees a fresh snapshot exactly like a
9
+ * local connection (docs/design/architecture.md §0).
10
+ */
11
+ import type { DatabaseSync } from "node:sqlite";
12
+ /**
13
+ * Build the facade. The cast is confined to this one construction site: the
14
+ * object structurally implements the read subset, a Proxy turns any other
15
+ * member access into a teaching error, and symbol probes (inspect, iterators)
16
+ * stay undefined so logging never explodes.
17
+ */
18
+ export declare function createDeputyDbFacade(env?: NodeJS.ProcessEnv): DatabaseSync;
@@ -0,0 +1,71 @@
1
+ import { reviveRow } from "./protocol.js";
2
+ import { fileSyncRequest } from "./routing.js";
3
+ const SQL_TIMEOUT_MS = 15_000;
4
+ function normalizeParams(params, sql) {
5
+ return params.map((param, index) => {
6
+ if (param === null || typeof param === "string" || typeof param === "number")
7
+ return param;
8
+ if (typeof param === "bigint") {
9
+ if (param > BigInt(Number.MAX_SAFE_INTEGER) || param < BigInt(Number.MIN_SAFE_INTEGER)) {
10
+ throw new TypeError(`deputy sql: bigint parameter ${index} exceeds JSON-safe range`);
11
+ }
12
+ return Number(param);
13
+ }
14
+ throw new TypeError(`deputy sql: unsupported ${typeof param} parameter at index ${index} for: ${sql.slice(0, 80)}`);
15
+ });
16
+ }
17
+ function queryRows(sql, params, env) {
18
+ // Rides the granted reader when present, else the deputy (routing.ts).
19
+ const res = fileSyncRequest({ verb: "sql", sql, params: normalizeParams(params, sql) }, SQL_TIMEOUT_MS, env);
20
+ return res["rows"].map(reviveRow);
21
+ }
22
+ function unsupported(member) {
23
+ return () => {
24
+ throw new Error(`DatabaseSync.${member} is not available on a deputy-routed connection — the deputy brokers read-only prepare/all/get only. Disable the helpers (THINGS_API_HELPERS=false) for local access.`);
25
+ };
26
+ }
27
+ /**
28
+ * Build the facade. The cast is confined to this one construction site: the
29
+ * object structurally implements the read subset, a Proxy turns any other
30
+ * member access into a teaching error, and symbol probes (inspect, iterators)
31
+ * stay undefined so logging never explodes.
32
+ */
33
+ export function createDeputyDbFacade(env = process.env) {
34
+ const base = {
35
+ prepare(sql) {
36
+ const statement = {
37
+ all(...params) {
38
+ return queryRows(sql, params, env);
39
+ },
40
+ get(...params) {
41
+ return queryRows(sql, params, env)[0];
42
+ },
43
+ run: unsupported("prepare(...).run (writes never touch the database directly)"),
44
+ iterate: unsupported("prepare(...).iterate"),
45
+ expandedSQL: sql,
46
+ sourceSQL: sql,
47
+ };
48
+ return new Proxy(statement, {
49
+ get(target, prop, receiver) {
50
+ if (typeof prop === "symbol" || prop in target)
51
+ return Reflect.get(target, prop, receiver);
52
+ return unsupported(`prepare(...).${String(prop)}`)();
53
+ },
54
+ });
55
+ },
56
+ exec: unsupported("exec"),
57
+ close() {
58
+ // The bridge outlives individual connections; nothing to release here.
59
+ },
60
+ isOpen: true,
61
+ isTransaction: false,
62
+ };
63
+ return new Proxy(base, {
64
+ get(target, prop, receiver) {
65
+ if (typeof prop === "symbol" || prop in target)
66
+ return Reflect.get(target, prop, receiver);
67
+ return unsupported(String(prop))();
68
+ },
69
+ });
70
+ }
71
+ //# sourceMappingURL=db-facade.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-facade.js","sourceRoot":"","sources":["../../src/deputy/db-facade.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function readContainerFileSync(path: string): Buffer;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Container-scoped file reads (Things prefs plists for sync-health and URL-
3
+ * scheme availability). The group container is TCC-protected like the
4
+ * database, so in deputy mode these reads ride the deputy's `read-file` verb —
5
+ * which the deputy confines to the container subtree. Direct mode is a plain
6
+ * readFileSync, byte-identical to the pre-deputy behavior.
7
+ */
8
+ import { readFileSync } from "node:fs";
9
+ import { deputyFilesActive, fileSyncRequest } from "./routing.js";
10
+ export function readContainerFileSync(path) {
11
+ if (!deputyFilesActive())
12
+ return readFileSync(path);
13
+ const res = fileSyncRequest({ verb: "read-file", path }, 10_000);
14
+ return Buffer.from(res["b64"], "base64");
15
+ }
16
+ //# sourceMappingURL=files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/deputy/files.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAElE,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,IAAI,CAAC,iBAAiB,EAAE;QAAE,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;IACpD,MAAM,GAAG,GAAG,eAAe,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC;IACjE,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAW,EAAE,QAAQ,CAAC,CAAC;AACrD,CAAC"}