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 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/deputy/protocol.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ import { type HelpersMode } from "../config.ts";
2
+ import { type DeputyHello, type ReaderHello } from "./protocol.ts";
3
+ export interface DeputyRouting {
4
+ /** True when requests are actually flowing to the deputy. */
5
+ readonly active: boolean;
6
+ /** Why routing is inactive ("disabled", or the activation failure). */
7
+ readonly reason: string | null;
8
+ /** Handshake result when active. */
9
+ readonly hello: DeputyHello | null;
10
+ }
11
+ /** Test seam: forget the per-process activation memo (and close transports). */
12
+ export declare function resetDeputyRoutingForTests(): void;
13
+ /** The per-process routing decision (activated lazily on first ask). */
14
+ export declare function deputyRouting(env?: NodeJS.ProcessEnv): DeputyRouting;
15
+ /** The reader transport's state (activated lazily; test seam via reset). */
16
+ export declare function readerRouting(env?: NodeJS.ProcessEnv): {
17
+ active: boolean;
18
+ granted: boolean;
19
+ hello: ReaderHello | null;
20
+ reason: string | null;
21
+ };
22
+ /**
23
+ * What routing actually RESOLVED to in this process: the configured mode plus
24
+ * whether each half is carrying traffic. Activates both halves (memoized), so
25
+ * it reports the same decision every other call in this process sees — doctor's
26
+ * helpers section reads it rather than re-deriving one.
27
+ */
28
+ export interface HelpersRouting {
29
+ mode: HelpersMode;
30
+ /** Automation verbs (osascript/shortcuts) ride the deputy. */
31
+ automation: boolean;
32
+ /** File verbs (sql/read-file/locate) ride the granted reader. */
33
+ files: boolean;
34
+ /** Why automation is not routed (null when it is). */
35
+ deputyReason: string | null;
36
+ /** Why file verbs are not routed (null when they are). */
37
+ readerReason: string | null;
38
+ }
39
+ export declare function helpersRouting(env?: NodeJS.ProcessEnv): HelpersRouting;
40
+ /** True when file verbs ride the reader (present, protocol-matched, granted). */
41
+ export declare function deputyFilesActive(env?: NodeJS.ProcessEnv): boolean;
42
+ /**
43
+ * Does this machine EXPECT the helpers to carry its reads?
44
+ *
45
+ * `true` is an explicit instruction, and under `auto` an installed bundle is
46
+ * the intent signal (src/deputy/agent-daemon.md §3c). The permissions doctrine
47
+ * hangs its no-fallback rule on this: when the helpers are expected but cannot
48
+ * serve, a read refuses loudly instead of quietly re-attaching consent to the
49
+ * terminal — the exact churn the helpers exist to end. A machine with nothing
50
+ * installed under `auto` is an ordinary direct machine and is NOT expecting
51
+ * them, so it falls through to the direct grants as it always has.
52
+ */
53
+ export declare function helpersExpected(env?: NodeJS.ProcessEnv): boolean;
54
+ /** Why the reader is not carrying reads (null when it is). */
55
+ export declare function readerUnavailableReason(env?: NodeJS.ProcessEnv): string | null;
56
+ /** Blocking FILE-verb round-trip via the granted reader. */
57
+ export declare function fileSyncRequest(fields: Record<string, unknown>, timeoutMs: number, env?: NodeJS.ProcessEnv): Record<string, unknown>;
58
+ /** Blocking round-trip via the bridge (facade + sync probes only). */
59
+ export declare function deputySyncRequest(fields: Record<string, unknown>, timeoutMs: number, env?: NodeJS.ProcessEnv): Record<string, unknown>;
60
+ /** Event-loop-friendly round-trip (vector dispatch). */
61
+ export declare function deputyAsyncRequest(fields: Record<string, unknown>, timeoutMs: number, env?: NodeJS.ProcessEnv): Promise<Record<string, unknown>>;
62
+ /**
63
+ * The reader-resolved container database path, or null when no granted reader
64
+ * is active (the caller then locates locally, exactly as before the helpers
65
+ * existed). The reader's scope is grant-checked, never prompted — a locate
66
+ * through it can refuse but can never stall on a consent dialog.
67
+ *
68
+ * A reader that IS serving and then fails to locate THROWS rather than
69
+ * returning null. Falling back to a direct locate there would silently move
70
+ * the read — and its consent — back onto the host app, which the permissions
71
+ * doctrine forbids (Article I; no-fallback rule). The reader's typed
72
+ * `not-granted` / `not-found` codes travel out on the error so the CLI can
73
+ * name the remedy.
74
+ */
75
+ export declare function deputyDbPath(env?: NodeJS.ProcessEnv): string | null;
76
+ /**
77
+ * Should DATABASE access route through the deputy? Only for the default
78
+ * container database: an explicit dbPath option or THINGS_DB env names a
79
+ * caller-chosen file (lab clones, fixtures) the deputy knows nothing about —
80
+ * those always open locally, deputy or no deputy.
81
+ */
82
+ export declare function deputyRoutesDb(options: {
83
+ dbPath?: string;
84
+ } | undefined, env?: NodeJS.ProcessEnv): boolean;
@@ -0,0 +1,422 @@
1
+ /**
2
+ * Deputy routing: decides ONCE per process whether privileged primitives (SQL
3
+ * reads, osascript, container file reads) go through the things-deputy broker
4
+ * or run direct exactly as they always have.
5
+ *
6
+ * Mode resolution (highest wins): the CLI `--helpers/--no-helpers` flag (which
7
+ * writes THINGS_API_HELPERS before any load) → THINGS_API_HELPERS env → stored
8
+ * `helpers-enabled` config → default `auto`. Direct execution is the contract's
9
+ * ground truth; the helpers are an alternative transport for the same
10
+ * primitives.
11
+ *
12
+ * The tri-state (docs/design/agent-daemon.md §3c):
13
+ *
14
+ * | mode | helper absent | installed, unhealthy | healthy, NOT onboarded | healthy + onboarded |
15
+ * |---------|----------------|----------------------|------------------------|---------------------|
16
+ * | `auto` | direct, SILENT | direct, LOUD | direct, LOUD | routed |
17
+ * | `true` | direct, LOUD | direct, LOUD | routed | routed |
18
+ * | `false` | direct, silent | direct, silent | direct, silent | direct, silent |
19
+ *
20
+ * Under `auto` installation IS the intent signal, so absence is not a
21
+ * degradation to report (a fresh machine must not nag) while an installed
22
+ * helper that cannot serve is — silence there would hide the very consent churn
23
+ * the helpers exist to end.
24
+ *
25
+ * There is no "installed but unpermissioned" routing state under `auto`: a
26
+ * deputy without an app-control grant for Things would move the consent dialog
27
+ * onto the helper, where nobody is watching for it, so it stays DORMANT until
28
+ * `things helpers setup` proves the grant. Each half is gated on its OWN
29
+ * requisite — writes on the deputy's `automation.things`, reads on the
30
+ * reader's bookmark grant — so a machine that finished half the ceremony gets
31
+ * the half it earned. Accessibility and System Events are NOT requisite: the
32
+ * UI vector is separately double-gated and refuses on its own.
33
+ *
34
+ * Fallback is decided at ACTIVATION, never mid-operation: if a helper is
35
+ * expected but unreachable (or speaks a different protocol), the whole process
36
+ * runs direct with one stderr notice — a half-routed operation is worse than
37
+ * an honestly direct one. A helper that dies mid-request surfaces as that
38
+ * request's error; it is never silently retried on the other path.
39
+ */
40
+ import { execFileSync } from "node:child_process";
41
+ import { existsSync, readFileSync } from "node:fs";
42
+ import { loadConfig } from "../config.js";
43
+ import { readRendezvousToken, rendezvousExists } from "../host-access.js";
44
+ import { DeputySyncBridge } from "./bridge.js";
45
+ import { DeputyAsyncClient } from "./client.js";
46
+ import { emitHelpersNotice, resetHelpersNoticeForTests } from "./notice.js";
47
+ import { DEPUTY_LAUNCHD_LABEL, DEPUTY_PROTOCOL_VERSION, DeputyRequestError, deputyInstalledBinaryPath, deputySocketPath, deputyTokenPath, EXPECTED_HELPERS_VERSION, readerInstalledAppPath, readerSocketPath, readerTokenPath, } from "./protocol.js";
48
+ let state = null;
49
+ let readerState = null;
50
+ /** Test seam: forget the per-process activation memo (and close transports). */
51
+ export function resetDeputyRoutingForTests() {
52
+ if (state?.active === true) {
53
+ state.bridge.close();
54
+ state.client.close();
55
+ }
56
+ readerState?.bridge?.close();
57
+ state = null;
58
+ readerState = null;
59
+ resetHelpersNoticeForTests();
60
+ }
61
+ /**
62
+ * Report a degradation — but only when the mode asks to hear about it. Under
63
+ * `auto` an ABSENT helper is an ordinary machine, not a fault: `loud` is false
64
+ * there and the process just runs direct.
65
+ */
66
+ function notice(loud, message) {
67
+ if (loud)
68
+ emitHelpersNotice(message);
69
+ }
70
+ function syncSleep(ms) {
71
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
72
+ }
73
+ function hello(bridge, token) {
74
+ const res = bridge.request({ v: DEPUTY_PROTOCOL_VERSION, token, verb: "hello" }, 2000);
75
+ if (res["ok"] !== true) {
76
+ const err = res["error"];
77
+ throw new DeputyRequestError(err?.code ?? "internal", err?.message ?? "handshake refused");
78
+ }
79
+ return res;
80
+ }
81
+ /**
82
+ * Version-skew policy: a PROTOCOL mismatch always deactivates (the shapes on
83
+ * the wire cannot be trusted). The helpers are versioned on their own line
84
+ * (EXPECTED_HELPERS_VERSION, decoupled from the package version so unchanged
85
+ * helpers never nag across package releases); a helpers-version mismatch on
86
+ * matching protocol gets one automatic `launchctl kickstart` (the installed
87
+ * bundle may already be newer on disk — the daily npm-link reality), then
88
+ * proceeds with a notice: the helpers' verbs are dumb primitives, so
89
+ * cross-version execution is safe by construction as long as the protocol
90
+ * matches.
91
+ */
92
+ function reconcileVersions(bridge, token, first) {
93
+ if (first.deputyVersion === EXPECTED_HELPERS_VERSION)
94
+ return first;
95
+ try {
96
+ execFileSync("launchctl", ["kickstart", "-k", `gui/${process.getuid?.() ?? 501}/${DEPUTY_LAUNCHD_LABEL}`],
97
+ // Clears the helpers' drain bound: kickstart -k waits for the old
98
+ // process, which finishes an in-flight request before exiting.
99
+ { stdio: "ignore", timeout: 30_000 });
100
+ }
101
+ catch {
102
+ // Not installed under launchd (foreground/test deputy) — nothing to restart.
103
+ notice(true, `installed helpers are v${first.deputyVersion}, this package expects v${EXPECTED_HELPERS_VERSION} (same protocol) — proceeding; rebuild with \`bash scripts/build-helpers.sh\` + \`things helpers setup\` to align`);
104
+ return first;
105
+ }
106
+ for (let attempt = 0; attempt < 8; attempt++) {
107
+ syncSleep(250);
108
+ try {
109
+ const fresh = hello(bridge, token);
110
+ if (fresh.deputyVersion === EXPECTED_HELPERS_VERSION)
111
+ return fresh;
112
+ }
113
+ catch {
114
+ // Restart still in flight — keep waiting out the bounded window.
115
+ }
116
+ }
117
+ const current = hello(bridge, token);
118
+ notice(true, `installed helpers are v${current.deputyVersion}, this package expects v${EXPECTED_HELPERS_VERSION} (same protocol) — proceeding; rebuild with \`bash scripts/build-helpers.sh\` + \`things helpers setup\` to align`);
119
+ return current;
120
+ }
121
+ /**
122
+ * Is a helper half INSTALLED on this machine? Installation is what separates
123
+ * "this host does not use the helpers" (silent under `auto`) from "the helper
124
+ * this host installed cannot serve" (always loud). The installed bundle on disk
125
+ * is the durable signal — a stopped launchd job leaves no socket but the bundle
126
+ * stays put.
127
+ */
128
+ function halfInstalled(path, socketPath, tokenPath) {
129
+ return existsSync(path) || (existsSync(socketPath) && existsSync(tokenPath));
130
+ }
131
+ function activate(env) {
132
+ const mode = loadConfig(env).helpersMode;
133
+ if (mode === "false")
134
+ return { active: false, reason: "disabled", hello: null };
135
+ const socketPath = deputySocketPath(env);
136
+ const tokenPath = deputyTokenPath(env);
137
+ const installed = halfInstalled(deputyInstalledBinaryPath(env), socketPath, tokenPath);
138
+ // `auto` + nothing installed = an ordinary un-onboarded machine, not a fault.
139
+ const loud = mode === "true" || installed;
140
+ if (!existsSync(socketPath) || !existsSync(tokenPath)) {
141
+ notice(loud, `${installed
142
+ ? `installed but not running (no socket at ${socketPath})`
143
+ : "not installed on this machine"} — running DIRECT, so TCC prompts attach to this process. \`things helpers ${installed ? "status` to inspect" : "setup` to change that"}.`);
144
+ return {
145
+ active: false,
146
+ reason: installed
147
+ ? `deputy not running (no socket at ${socketPath})`
148
+ : "deputy not installed",
149
+ hello: null,
150
+ };
151
+ }
152
+ const token = readFileSync(tokenPath, "utf8").trim();
153
+ const bridge = new DeputySyncBridge(socketPath);
154
+ let helloResult;
155
+ try {
156
+ helloResult = reconcileVersions(bridge, token, hello(bridge, token));
157
+ }
158
+ catch (err) {
159
+ bridge.close();
160
+ const why = err instanceof Error ? err.message : String(err);
161
+ // A socket that will not handshake is a broken helper under EVERY non-off
162
+ // mode — never silent, whatever the mode says about absence.
163
+ notice(true, `the handshake failed (${why}) — running DIRECT. \`things helpers restart\`, then \`things helpers status\` to inspect.`);
164
+ return { active: false, reason: `handshake failed: ${why}`, hello: null };
165
+ }
166
+ if (helloResult.protocol !== DEPUTY_PROTOCOL_VERSION) {
167
+ bridge.close();
168
+ notice(true, `the deputy speaks protocol ${helloResult.protocol}, this package speaks ${DEPUTY_PROTOCOL_VERSION} — running DIRECT. Rebuild with \`bash scripts/build-helpers.sh\` + \`things helpers setup\`.`);
169
+ return {
170
+ active: false,
171
+ reason: `protocol skew (deputy ${helloResult.protocol}, library ${DEPUTY_PROTOCOL_VERSION})`,
172
+ hello: null,
173
+ };
174
+ }
175
+ // The onboarding gate. Routing writes through a deputy that has no
176
+ // app-control grant for Things does not move the consent surface anywhere —
177
+ // it just relocates the dialog to the helper, where nobody is looking. Under
178
+ // `auto` (installation is the intent signal, not a promise) the deputy must
179
+ // PROVE the grant before it carries traffic; `true` is an explicit
180
+ // instruction to route regardless and stays loud on failure.
181
+ const automationThings = helloResult.automation?.things;
182
+ if (mode === "auto" && automationThings !== "granted") {
183
+ bridge.close();
184
+ // Absent fields = helpers predating the TCC handshake. Not provably
185
+ // onboarded is not onboarded: fail closed rather than guess.
186
+ const reason = automationThings === undefined
187
+ ? `onboarding not provable (helpers v${helloResult.deputyVersion} predate the permission handshake)`
188
+ : `onboarding incomplete (automation → Things: ${automationThings})`;
189
+ notice(true, automationThings === undefined
190
+ ? `the installed helpers (v${helloResult.deputyVersion}) cannot report their macOS permission standing, so app automation runs DIRECT — rebuild with \`bash scripts/build-helpers.sh\`, then \`things helpers setup\`.`
191
+ : `the helpers have no app-control permission for Things (${automationThings}), so app automation runs DIRECT — \`things helpers setup\` settles it in one sitting.`);
192
+ return { active: false, reason, hello: null };
193
+ }
194
+ return {
195
+ active: true,
196
+ reason: null,
197
+ hello: helloResult,
198
+ token,
199
+ bridge,
200
+ client: new DeputyAsyncClient(socketPath),
201
+ };
202
+ }
203
+ /** The per-process routing decision (activated lazily on first ask). */
204
+ export function deputyRouting(env = process.env) {
205
+ state ??= activate(env);
206
+ return state;
207
+ }
208
+ function activeState(env) {
209
+ const routing = deputyRouting(env);
210
+ return routing.active ? state : null;
211
+ }
212
+ function readerInactive(reason) {
213
+ return {
214
+ active: false,
215
+ granted: false,
216
+ hello: null,
217
+ token: "",
218
+ bridge: null,
219
+ reason,
220
+ };
221
+ }
222
+ function activateReader(env) {
223
+ const mode = loadConfig(env).helpersMode;
224
+ if (mode === "false")
225
+ return readerInactive("disabled");
226
+ // The rendezvous is `<state>/reader` — our own directory, outside every App
227
+ // Sandbox container — so these are ordinary file touches from any host app.
228
+ // No guard, no consent class, nothing to prove before looking.
229
+ const socketPath = readerSocketPath(env);
230
+ const tokenPath = readerTokenPath(env);
231
+ const installed = halfInstalled(readerInstalledAppPath(env), socketPath, tokenPath);
232
+ if (!rendezvousExists(socketPath) || !rendezvousExists(tokenPath)) {
233
+ // launchd creates the socket when the reader's LaunchAgent is loaded, and
234
+ // install mints the token beside it — so an absent rendezvous means the
235
+ // pair was never installed here, or its LaunchAgent is not loaded.
236
+ // Absence is silent under `auto`; under `true` the caller asserted routing.
237
+ // An UNGRANTED reader is deliberately NOT noticed here — that is the
238
+ // ceremony's own state, reported by `things helpers status` and doctor.
239
+ notice(mode === "true" || installed, installed
240
+ ? `the reader is installed but not registered with launchd (no rendezvous at ${socketPath}) — database reads run DIRECT. \`things helpers setup\` to re-register it.`
241
+ : "the reader is not installed on this machine — database reads run DIRECT. `things helpers setup` to change that.");
242
+ return readerInactive(installed ? `reader not registered with launchd (no ${socketPath})` : "reader not installed");
243
+ }
244
+ const token = readRendezvousToken(tokenPath);
245
+ if (token === null) {
246
+ notice(true, `the reader's access token could not be read (${tokenPath}) — database reads run DIRECT. \`things helpers setup\` to mint a fresh one.`);
247
+ return readerInactive(`the reader's access token could not be read (${tokenPath})`);
248
+ }
249
+ const bridge = new DeputySyncBridge(socketPath);
250
+ try {
251
+ const res = bridge.request({ v: DEPUTY_PROTOCOL_VERSION, token, verb: "hello" }, 2000);
252
+ if (res["ok"] !== true)
253
+ throw new DeputyRequestError("handshake", JSON.stringify(res["error"]));
254
+ const readerHello = res;
255
+ if (readerHello.protocol !== DEPUTY_PROTOCOL_VERSION) {
256
+ bridge.close();
257
+ notice(true, `the reader speaks protocol ${readerHello.protocol}, this package speaks ${DEPUTY_PROTOCOL_VERSION} — database reads run DIRECT. Rebuild with \`bash scripts/build-helpers.sh\` + \`things helpers setup\`.`);
258
+ return readerInactive(`protocol skew (reader ${readerHello.protocol})`);
259
+ }
260
+ return {
261
+ active: true,
262
+ granted: readerHello.granted === true,
263
+ hello: readerHello,
264
+ token,
265
+ bridge,
266
+ reason: null,
267
+ };
268
+ }
269
+ catch (err) {
270
+ bridge.close();
271
+ const why = err instanceof Error ? err.message : String(err);
272
+ notice(true, `the reader handshake failed (${why}) — database reads run DIRECT. \`things helpers restart\`, then \`things helpers status\` to inspect.`);
273
+ return readerInactive(`reader handshake failed: ${why}`);
274
+ }
275
+ }
276
+ /** The reader transport's state (activated lazily; test seam via reset). */
277
+ export function readerRouting(env = process.env) {
278
+ readerState ??= activateReader(env);
279
+ return readerState;
280
+ }
281
+ /**
282
+ * The transport serving FILE verbs (sql / read-file / locate): the sandboxed
283
+ * reader when present AND granted, else null (direct local access). ONLY the
284
+ * reader — the deputy is mutations-only by design (the maintainer's ruling
285
+ * 2026-08-21: no multi-step fallback chains; its container access would ride
286
+ * the per-process consent class this pair exists to end). A reader that dies
287
+ * mid-request errors that request honestly, never a silent transport switch.
288
+ */
289
+ function fileTransport(env) {
290
+ const reader = readerRouting(env);
291
+ if (reader.active && reader.granted) {
292
+ const rs = readerState;
293
+ return { bridge: rs.bridge, token: rs.token };
294
+ }
295
+ return null;
296
+ }
297
+ export function helpersRouting(env = process.env) {
298
+ const mode = loadConfig(env).helpersMode;
299
+ const deputy = deputyRouting(env);
300
+ const reader = readerRouting(env);
301
+ const files = deputyFilesActive(env);
302
+ return {
303
+ mode,
304
+ automation: deputy.active,
305
+ files,
306
+ deputyReason: deputy.reason,
307
+ readerReason: files
308
+ ? null
309
+ : reader.active && !reader.granted
310
+ ? "reader running but NOT granted (things helpers setup)"
311
+ : reader.reason,
312
+ };
313
+ }
314
+ /** True when file verbs ride the reader (present, protocol-matched, granted). */
315
+ export function deputyFilesActive(env = process.env) {
316
+ return fileTransport(env) !== null;
317
+ }
318
+ /**
319
+ * Does this machine EXPECT the helpers to carry its reads?
320
+ *
321
+ * `true` is an explicit instruction, and under `auto` an installed bundle is
322
+ * the intent signal (src/deputy/agent-daemon.md §3c). The permissions doctrine
323
+ * hangs its no-fallback rule on this: when the helpers are expected but cannot
324
+ * serve, a read refuses loudly instead of quietly re-attaching consent to the
325
+ * terminal — the exact churn the helpers exist to end. A machine with nothing
326
+ * installed under `auto` is an ordinary direct machine and is NOT expecting
327
+ * them, so it falls through to the direct grants as it always has.
328
+ */
329
+ export function helpersExpected(env = process.env) {
330
+ const mode = loadConfig(env).helpersMode;
331
+ if (mode === "false")
332
+ return false;
333
+ if (mode === "true")
334
+ return true;
335
+ // Both halves of the question live in our own state directory now — the
336
+ // installed bundle and the rendezvous alike — so this is always answerable
337
+ // from any host, with no probe that could prompt.
338
+ if (existsSync(readerInstalledAppPath(env)))
339
+ return true;
340
+ return rendezvousExists(readerSocketPath(env)) && rendezvousExists(readerTokenPath(env));
341
+ }
342
+ /** Why the reader is not carrying reads (null when it is). */
343
+ export function readerUnavailableReason(env = process.env) {
344
+ if (deputyFilesActive(env))
345
+ return null;
346
+ const reader = readerRouting(env);
347
+ if (reader.active && !reader.granted) {
348
+ return "the reader is running but holds no read grant for the Things data folder";
349
+ }
350
+ return reader.reason;
351
+ }
352
+ /** Blocking FILE-verb round-trip via the granted reader. */
353
+ export function fileSyncRequest(fields, timeoutMs, env = process.env) {
354
+ const transport = fileTransport(env);
355
+ if (transport === null) {
356
+ throw new DeputyRequestError("inactive", "the reader is not active");
357
+ }
358
+ return unwrap(transport.bridge.request({ v: DEPUTY_PROTOCOL_VERSION, token: transport.token, ...fields }, timeoutMs));
359
+ }
360
+ /** Unwrap a protocol response: return it on ok, throw DeputyRequestError otherwise. */
361
+ function unwrap(res) {
362
+ if (res["ok"] === true)
363
+ return res;
364
+ const err = res["error"];
365
+ throw new DeputyRequestError(err?.code ?? "internal", err?.message ?? "deputy refused the request");
366
+ }
367
+ /** Blocking round-trip via the bridge (facade + sync probes only). */
368
+ export function deputySyncRequest(fields, timeoutMs, env = process.env) {
369
+ const active = activeState(env);
370
+ if (active === null)
371
+ throw new DeputyRequestError("inactive", "deputy routing is not active");
372
+ return unwrap(active.bridge.request({ v: DEPUTY_PROTOCOL_VERSION, token: active.token, ...fields }, timeoutMs));
373
+ }
374
+ /** Event-loop-friendly round-trip (vector dispatch). */
375
+ export async function deputyAsyncRequest(fields, timeoutMs, env = process.env) {
376
+ const active = activeState(env);
377
+ if (active === null)
378
+ throw new DeputyRequestError("inactive", "deputy routing is not active");
379
+ return unwrap(await active.client.request({ v: DEPUTY_PROTOCOL_VERSION, token: active.token, ...fields }, timeoutMs));
380
+ }
381
+ /**
382
+ * The reader-resolved container database path, or null when no granted reader
383
+ * is active (the caller then locates locally, exactly as before the helpers
384
+ * existed). The reader's scope is grant-checked, never prompted — a locate
385
+ * through it can refuse but can never stall on a consent dialog.
386
+ *
387
+ * A reader that IS serving and then fails to locate THROWS rather than
388
+ * returning null. Falling back to a direct locate there would silently move
389
+ * the read — and its consent — back onto the host app, which the permissions
390
+ * doctrine forbids (Article I; no-fallback rule). The reader's typed
391
+ * `not-granted` / `not-found` codes travel out on the error so the CLI can
392
+ * name the remedy.
393
+ */
394
+ export function deputyDbPath(env = process.env) {
395
+ const reader = readerRouting(env);
396
+ if (!reader.active || !reader.granted)
397
+ return null;
398
+ if (reader.hello?.dbPath != null)
399
+ return reader.hello.dbPath;
400
+ const rs = readerState;
401
+ if (rs.dbPathMemo !== undefined && rs.dbPathMemo !== null)
402
+ return rs.dbPathMemo;
403
+ const res = fileSyncRequest({ verb: "locate" }, 10_000, env);
404
+ const path = typeof res["path"] === "string" ? res["path"] : null;
405
+ if (path === null) {
406
+ throw new DeputyRequestError("not-found", "the reader answered the locate but named no database");
407
+ }
408
+ rs.dbPathMemo = path;
409
+ return path;
410
+ }
411
+ /**
412
+ * Should DATABASE access route through the deputy? Only for the default
413
+ * container database: an explicit dbPath option or THINGS_DB env names a
414
+ * caller-chosen file (lab clones, fixtures) the deputy knows nothing about —
415
+ * those always open locally, deputy or no deputy.
416
+ */
417
+ export function deputyRoutesDb(options, env = process.env) {
418
+ if (options?.dbPath !== undefined || (env["THINGS_DB"] ?? "") !== "")
419
+ return false;
420
+ return deputyFilesActive(env);
421
+ }
422
+ //# sourceMappingURL=routing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routing.js","sourceRoot":"","sources":["../../src/deputy/routing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export interface ShortcutsRunResult {
2
+ exitCode: number;
3
+ stdout: string;
4
+ stderr: string;
5
+ timedOut?: boolean;
6
+ }
7
+ /** `shortcuts run <name> --input-path … --output-path …` (the write vector's shape). */
8
+ export declare function shortcutsRunExec(name: string, inputPath: string, outputPath: string, timeoutMs: number): Promise<ShortcutsRunResult>;
9
+ /** `shortcuts list` (availability's proxy census). Returns stdout; throws on failure. */
10
+ export declare function shortcutsListSync(timeoutMs?: number): string;
@@ -0,0 +1,50 @@
1
+ /**
2
+ * The Apple Shortcuts execution seam — the `shortcuts` CLI twin of osa.ts.
3
+ * Both call sites (the shortcuts write vector's `run`, availability's `list`)
4
+ * route through the deputy when it is active, so every app-automation surface
5
+ * shares the deputy's one stable identity; direct mode is byte-identical to
6
+ * the pre-deputy behavior. The deputy only accepts this library's bundled
7
+ * `things-proxy-*` shortcut names — it is a paired tool, not a general
8
+ * shortcut runner.
9
+ */
10
+ import { execFile, execFileSync } from "node:child_process";
11
+ import {} from "./protocol.js";
12
+ import { deputyAsyncRequest, deputyRouting, deputySyncRequest } from "./routing.js";
13
+ /** Deputy-side kill fires at timeoutMs; the client deadline adds grace so the deputy's honest answer wins. */
14
+ const CLIENT_GRACE_MS = 5000;
15
+ /** `shortcuts run <name> --input-path … --output-path …` (the write vector's shape). */
16
+ export async function shortcutsRunExec(name, inputPath, outputPath, timeoutMs) {
17
+ if (deputyRouting().active) {
18
+ const res = (await deputyAsyncRequest({ verb: "shortcuts", op: "run", name, inputPath, outputPath, timeoutMs }, timeoutMs + CLIENT_GRACE_MS));
19
+ return {
20
+ exitCode: res.timedOut === true && res.exitCode === 0 ? 1 : res.exitCode,
21
+ stdout: res.stdout,
22
+ stderr: res.stderr,
23
+ ...(res.timedOut === true && { timedOut: true }),
24
+ };
25
+ }
26
+ return new Promise((resolve) => {
27
+ execFile("shortcuts", ["run", name, "--input-path", inputPath, "--output-path", outputPath], { timeout: timeoutMs }, (err, stdout, stderr) => {
28
+ // A deadline kill (err.killed) is the signature of an unanswered
29
+ // first-run consent dialog — surfaced distinctly for attribution.
30
+ const timedOut = err !== null && err.killed === true;
31
+ resolve({
32
+ exitCode: err === null ? 0 : (err.code ?? 1),
33
+ stdout: String(stdout),
34
+ stderr: String(stderr),
35
+ ...(timedOut && { timedOut: true }),
36
+ });
37
+ });
38
+ });
39
+ }
40
+ /** `shortcuts list` (availability's proxy census). Returns stdout; throws on failure. */
41
+ export function shortcutsListSync(timeoutMs = 10_000) {
42
+ if (!deputyRouting().active) {
43
+ return execFileSync("shortcuts", ["list"], { encoding: "utf8", timeout: timeoutMs });
44
+ }
45
+ const res = deputySyncRequest({ verb: "shortcuts", op: "list", timeoutMs }, timeoutMs + CLIENT_GRACE_MS);
46
+ if (res.exitCode === 0 && res.timedOut !== true)
47
+ return res.stdout;
48
+ throw new Error(`Command failed: shortcuts list\n${res.stderr}`);
49
+ }
50
+ //# sourceMappingURL=shortcuts-exec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shortcuts-exec.js","sourceRoot":"","sources":["../../src/deputy/shortcuts-exec.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE5D,OAAO,EAAwB,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEpF,8GAA8G;AAC9G,MAAM,eAAe,GAAG,IAAI,CAAC;AAS7B,wFAAwF;AACxF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAAY,EACZ,SAAiB,EACjB,UAAkB,EAClB,SAAiB;IAEjB,IAAI,aAAa,EAAE,CAAC,MAAM,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,CAAC,MAAM,kBAAkB,CACnC,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,EACxE,SAAS,GAAG,eAAe,CAC5B,CAA+B,CAAC;QACjC,OAAO;YACL,QAAQ,EAAE,GAAG,CAAC,QAAQ,KAAK,IAAI,IAAI,GAAG,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ;YACxE,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,GAAG,CAAC,GAAG,CAAC,QAAQ,KAAK,IAAI,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;SACjD,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,QAAQ,CACN,WAAW,EACX,CAAC,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,SAAS,EAAE,eAAe,EAAE,UAAU,CAAC,EACrE,EAAE,OAAO,EAAE,SAAS,EAAE,EACtB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YACtB,iEAAiE;YACjE,kEAAkE;YAClE,MAAM,QAAQ,GAAG,GAAG,KAAK,IAAI,IAAK,GAA4B,CAAC,MAAM,KAAK,IAAI,CAAC;YAC/E,OAAO,CAAC;gBACN,QAAQ,EAAE,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,GAAyB,CAAC,IAAI,IAAI,CAAC,CAAC;gBACnE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC;gBACtB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC;gBACtB,GAAG,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;aACpC,CAAC,CAAC;QACL,CAAC,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,iBAAiB,CAAC,SAAS,GAAG,MAAM;IAClD,IAAI,CAAC,aAAa,EAAE,CAAC,MAAM,EAAE,CAAC;QAC5B,OAAO,YAAY,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;IACvF,CAAC;IACD,MAAM,GAAG,GAAG,iBAAiB,CAC3B,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,EAC5C,SAAS,GAAG,eAAe,CACE,CAAC;IAChC,IAAI,GAAG,CAAC,QAAQ,KAAK,CAAC,IAAI,GAAG,CAAC,QAAQ,KAAK,IAAI;QAAE,OAAO,GAAG,CAAC,MAAM,CAAC;IACnE,MAAM,IAAI,KAAK,CAAC,mCAAmC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;AACnE,CAAC"}