@moxxy/plugin-computer-control 0.41.2 → 0.42.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 (269) hide show
  1. package/bin/win32-x64/moxxy-computer.exe +0 -0
  2. package/bin/win32-x64/moxxy-computer.exe.json +1 -1
  3. package/dist/backend/access.d.ts +129 -0
  4. package/dist/backend/access.d.ts.map +1 -0
  5. package/dist/backend/access.js +158 -0
  6. package/dist/backend/access.js.map +1 -0
  7. package/dist/backend/app-hints.d.ts +14 -0
  8. package/dist/backend/app-hints.d.ts.map +1 -0
  9. package/dist/backend/app-hints.js +30 -0
  10. package/dist/backend/app-hints.js.map +1 -0
  11. package/dist/backend/backend.d.ts +70 -0
  12. package/dist/backend/backend.d.ts.map +1 -0
  13. package/dist/backend/backend.js +466 -0
  14. package/dist/backend/backend.js.map +1 -0
  15. package/dist/backend/rpc.d.ts +1438 -0
  16. package/dist/backend/rpc.d.ts.map +1 -0
  17. package/dist/backend/rpc.js +75 -0
  18. package/dist/backend/rpc.js.map +1 -0
  19. package/dist/backend/turn-controls.d.ts +20 -0
  20. package/dist/backend/turn-controls.d.ts.map +1 -0
  21. package/dist/backend/turn-controls.js +115 -0
  22. package/dist/backend/turn-controls.js.map +1 -0
  23. package/dist/contract/guidance.d.ts +12 -0
  24. package/dist/contract/guidance.d.ts.map +1 -0
  25. package/dist/contract/guidance.js +42 -0
  26. package/dist/contract/guidance.js.map +1 -0
  27. package/dist/contract/image.d.ts +29 -0
  28. package/dist/contract/image.d.ts.map +1 -0
  29. package/dist/contract/image.js +46 -0
  30. package/dist/contract/image.js.map +1 -0
  31. package/dist/contract/keys.d.ts +15 -0
  32. package/dist/contract/keys.d.ts.map +1 -0
  33. package/dist/contract/keys.js +118 -0
  34. package/dist/contract/keys.js.map +1 -0
  35. package/dist/contract/outcome.d.ts +61 -0
  36. package/dist/contract/outcome.d.ts.map +1 -0
  37. package/dist/contract/outcome.js +63 -0
  38. package/dist/contract/outcome.js.map +1 -0
  39. package/dist/contract/progress.d.ts +27 -0
  40. package/dist/contract/progress.d.ts.map +1 -0
  41. package/dist/contract/progress.js +36 -0
  42. package/dist/contract/progress.js.map +1 -0
  43. package/dist/contract/tools.d.ts +338 -0
  44. package/dist/contract/tools.d.ts.map +1 -0
  45. package/dist/contract/tools.js +195 -0
  46. package/dist/contract/tools.js.map +1 -0
  47. package/dist/contract/untrusted.d.ts +3 -0
  48. package/dist/contract/untrusted.d.ts.map +1 -0
  49. package/dist/contract/untrusted.js +8 -0
  50. package/dist/contract/untrusted.js.map +1 -0
  51. package/dist/helper/artifact.d.ts +41 -0
  52. package/dist/helper/artifact.d.ts.map +1 -0
  53. package/dist/helper/artifact.js +189 -0
  54. package/dist/helper/artifact.js.map +1 -0
  55. package/dist/helper/protocol.d.ts +80 -0
  56. package/dist/helper/protocol.d.ts.map +1 -0
  57. package/dist/helper/protocol.js +49 -0
  58. package/dist/helper/protocol.js.map +1 -0
  59. package/dist/helper/transport.d.ts +43 -0
  60. package/dist/helper/transport.d.ts.map +1 -0
  61. package/dist/{windows → helper}/transport.js +45 -19
  62. package/dist/helper/transport.js.map +1 -0
  63. package/dist/index.d.ts +9 -22
  64. package/dist/index.d.ts.map +1 -1
  65. package/dist/index.js +35 -42
  66. package/dist/index.js.map +1 -1
  67. package/dist/jev/ladder.d.ts +32 -0
  68. package/dist/jev/ladder.d.ts.map +1 -0
  69. package/dist/jev/ladder.js +66 -0
  70. package/dist/jev/ladder.js.map +1 -0
  71. package/dist/jev/memory.d.ts +11 -0
  72. package/dist/jev/memory.d.ts.map +1 -0
  73. package/dist/jev/memory.js +16 -0
  74. package/dist/jev/memory.js.map +1 -0
  75. package/dist/jev/run.d.ts +93 -0
  76. package/dist/jev/run.d.ts.map +1 -0
  77. package/dist/jev/run.js +403 -0
  78. package/dist/jev/run.js.map +1 -0
  79. package/dist/jev/train.d.ts +97 -0
  80. package/dist/jev/train.d.ts.map +1 -0
  81. package/dist/jev/train.js +28 -0
  82. package/dist/jev/train.js.map +1 -0
  83. package/dist/linux/profile.d.ts +6 -0
  84. package/dist/linux/profile.d.ts.map +1 -0
  85. package/dist/linux/profile.js +21 -0
  86. package/dist/linux/profile.js.map +1 -0
  87. package/dist/macos/profile.d.ts +5 -0
  88. package/dist/macos/profile.d.ts.map +1 -0
  89. package/dist/macos/profile.js +17 -0
  90. package/dist/macos/profile.js.map +1 -0
  91. package/dist/preview/controller.d.ts +127 -0
  92. package/dist/preview/controller.d.ts.map +1 -0
  93. package/dist/preview/controller.js +203 -0
  94. package/dist/preview/controller.js.map +1 -0
  95. package/dist/preview/surface.d.ts +9 -0
  96. package/dist/preview/surface.d.ts.map +1 -0
  97. package/dist/preview/surface.js +50 -0
  98. package/dist/preview/surface.js.map +1 -0
  99. package/dist/windows/maintenance.d.ts +1 -1
  100. package/dist/windows/maintenance.d.ts.map +1 -1
  101. package/dist/windows/maintenance.js +6 -5
  102. package/dist/windows/maintenance.js.map +1 -1
  103. package/dist/windows/profile.d.ts +5 -0
  104. package/dist/windows/profile.d.ts.map +1 -0
  105. package/dist/windows/profile.js +17 -0
  106. package/dist/windows/profile.js.map +1 -0
  107. package/learned/README.md +26 -0
  108. package/learned/cases/com.apple.calculator.json +395 -0
  109. package/learned/cases/com.apple.finder.json +115 -0
  110. package/learned/cases/com.apple.safari.json +112 -0
  111. package/learned/cases/com.apple.systempreferences.json +255 -0
  112. package/learned/com.apple.calculator-eace95fc.json +334 -0
  113. package/learned/com.apple.finder-27cf6ce8.json +260 -0
  114. package/learned/com.apple.safari-7cd9df4f.json +143 -0
  115. package/learned/com.apple.systempreferences-02cf0b8b.json +535 -0
  116. package/package.json +13 -7
  117. package/scripts/promote-learned.mjs +8 -0
  118. package/scripts/summarize-trial.mjs +68 -0
  119. package/scripts/train-learned.mjs +64 -0
  120. package/skills/computer-apps/blender.md +29 -0
  121. package/skills/computer-apps/browsers.md +50 -0
  122. package/skills/computer-apps/design-tools.md +37 -0
  123. package/skills/computer-apps/finder.md +23 -0
  124. package/skills/computer-apps/office.md +46 -0
  125. package/skills/computer-apps/video-editors.md +44 -0
  126. package/skills/computer-control.md +154 -191
  127. package/src/backend/access.test.ts +158 -0
  128. package/src/backend/access.ts +168 -0
  129. package/src/backend/app-hints.test.ts +59 -0
  130. package/src/backend/app-hints.ts +39 -0
  131. package/src/backend/backend.test.ts +725 -0
  132. package/src/backend/backend.ts +482 -0
  133. package/src/backend/contract-helper.fixture.mjs +138 -0
  134. package/src/backend/helper.fixture.ts +38 -0
  135. package/src/backend/rpc.ts +90 -0
  136. package/src/backend/turn-controls.test.ts +178 -0
  137. package/src/backend/turn-controls.ts +120 -0
  138. package/src/contract/guidance.test.ts +75 -0
  139. package/src/contract/guidance.ts +48 -0
  140. package/src/contract/image.test.ts +74 -0
  141. package/src/contract/image.ts +54 -0
  142. package/src/contract/keys.test.ts +103 -0
  143. package/src/contract/keys.ts +117 -0
  144. package/src/contract/outcome.test.ts +71 -0
  145. package/src/contract/outcome.ts +72 -0
  146. package/src/contract/progress.test.ts +56 -0
  147. package/src/contract/progress.ts +43 -0
  148. package/src/contract/tools.test.ts +210 -0
  149. package/src/contract/tools.ts +212 -0
  150. package/src/contract/untrusted.test.ts +20 -0
  151. package/src/contract/untrusted.ts +8 -0
  152. package/src/helper/artifact.test.ts +131 -0
  153. package/src/helper/artifact.ts +182 -0
  154. package/src/helper/protocol.test.ts +29 -0
  155. package/src/helper/protocol.ts +50 -0
  156. package/src/{windows → helper}/transport.test.ts +76 -19
  157. package/src/{windows → helper}/transport.ts +54 -16
  158. package/src/index.test.ts +112 -0
  159. package/src/index.ts +36 -53
  160. package/src/jev/ladder.test.ts +113 -0
  161. package/src/jev/ladder.ts +88 -0
  162. package/src/jev/memory.ts +20 -0
  163. package/src/jev/run.test.ts +700 -0
  164. package/src/jev/run.ts +443 -0
  165. package/src/jev/train.test.ts +40 -0
  166. package/src/jev/train.ts +41 -0
  167. package/src/linux/helper.test.ts +481 -0
  168. package/src/linux/profile.ts +25 -0
  169. package/src/macos/helper.test.ts +988 -0
  170. package/src/macos/profile.ts +19 -0
  171. package/src/preview/controller.test.ts +308 -0
  172. package/src/preview/controller.ts +262 -0
  173. package/src/preview/surface.test.ts +68 -0
  174. package/src/preview/surface.ts +45 -0
  175. package/src/skill.test.ts +34 -0
  176. package/src/windows/maintenance.ts +8 -7
  177. package/src/windows/profile.ts +19 -0
  178. package/dist/shell.d.ts +0 -56
  179. package/dist/shell.d.ts.map +0 -1
  180. package/dist/shell.js +0 -189
  181. package/dist/shell.js.map +0 -1
  182. package/dist/temporary-files.d.ts +0 -2
  183. package/dist/temporary-files.d.ts.map +0 -1
  184. package/dist/temporary-files.js +0 -10
  185. package/dist/temporary-files.js.map +0 -1
  186. package/dist/tools/applescript.d.ts +0 -2
  187. package/dist/tools/applescript.d.ts.map +0 -1
  188. package/dist/tools/applescript.js +0 -50
  189. package/dist/tools/applescript.js.map +0 -1
  190. package/dist/tools/click.d.ts +0 -2
  191. package/dist/tools/click.d.ts.map +0 -1
  192. package/dist/tools/click.js +0 -58
  193. package/dist/tools/click.js.map +0 -1
  194. package/dist/tools/clipboard.d.ts +0 -2
  195. package/dist/tools/clipboard.d.ts.map +0 -1
  196. package/dist/tools/clipboard.js +0 -71
  197. package/dist/tools/clipboard.js.map +0 -1
  198. package/dist/tools/key.d.ts +0 -11
  199. package/dist/tools/key.d.ts.map +0 -1
  200. package/dist/tools/key.js +0 -143
  201. package/dist/tools/key.js.map +0 -1
  202. package/dist/tools/open.d.ts +0 -2
  203. package/dist/tools/open.d.ts.map +0 -1
  204. package/dist/tools/open.js +0 -91
  205. package/dist/tools/open.js.map +0 -1
  206. package/dist/tools/screenshot.d.ts +0 -2
  207. package/dist/tools/screenshot.d.ts.map +0 -1
  208. package/dist/tools/screenshot.js +0 -162
  209. package/dist/tools/screenshot.js.map +0 -1
  210. package/dist/tools/type.d.ts +0 -8
  211. package/dist/tools/type.d.ts.map +0 -1
  212. package/dist/tools/type.js +0 -65
  213. package/dist/tools/type.js.map +0 -1
  214. package/dist/windows/artifact.d.ts +0 -3
  215. package/dist/windows/artifact.d.ts.map +0 -1
  216. package/dist/windows/artifact.js +0 -57
  217. package/dist/windows/artifact.js.map +0 -1
  218. package/dist/windows/backend.d.ts +0 -11
  219. package/dist/windows/backend.d.ts.map +0 -1
  220. package/dist/windows/backend.js +0 -122
  221. package/dist/windows/backend.js.map +0 -1
  222. package/dist/windows/contracts.d.ts +0 -1627
  223. package/dist/windows/contracts.d.ts.map +0 -1
  224. package/dist/windows/contracts.js +0 -137
  225. package/dist/windows/contracts.js.map +0 -1
  226. package/dist/windows/control-service.d.ts +0 -12
  227. package/dist/windows/control-service.d.ts.map +0 -1
  228. package/dist/windows/control-service.js +0 -65
  229. package/dist/windows/control-service.js.map +0 -1
  230. package/dist/windows/guidance.d.ts +0 -3
  231. package/dist/windows/guidance.d.ts.map +0 -1
  232. package/dist/windows/guidance.js +0 -20
  233. package/dist/windows/guidance.js.map +0 -1
  234. package/dist/windows/protocol.d.ts +0 -9
  235. package/dist/windows/protocol.d.ts.map +0 -1
  236. package/dist/windows/protocol.js +0 -32
  237. package/dist/windows/protocol.js.map +0 -1
  238. package/dist/windows/transport.d.ts +0 -23
  239. package/dist/windows/transport.d.ts.map +0 -1
  240. package/dist/windows/transport.js.map +0 -1
  241. package/src/shell.test.ts +0 -186
  242. package/src/shell.ts +0 -213
  243. package/src/temporary-files.test.ts +0 -18
  244. package/src/temporary-files.ts +0 -9
  245. package/src/tools/applescript-serialize.test.ts +0 -74
  246. package/src/tools/applescript.ts +0 -53
  247. package/src/tools/click.ts +0 -60
  248. package/src/tools/clipboard.ts +0 -72
  249. package/src/tools/key.ts +0 -155
  250. package/src/tools/open.ts +0 -96
  251. package/src/tools/screenshot.test.ts +0 -137
  252. package/src/tools/screenshot.ts +0 -180
  253. package/src/tools/type.ts +0 -68
  254. package/src/tools.test.ts +0 -94
  255. package/src/windows/action-contracts.test.ts +0 -13
  256. package/src/windows/artifact.test.ts +0 -16
  257. package/src/windows/artifact.ts +0 -57
  258. package/src/windows/backend.test.ts +0 -41
  259. package/src/windows/backend.ts +0 -122
  260. package/src/windows/contracts.test.ts +0 -81
  261. package/src/windows/contracts.ts +0 -143
  262. package/src/windows/control-service.test.ts +0 -58
  263. package/src/windows/control-service.ts +0 -68
  264. package/src/windows/guidance.test.ts +0 -29
  265. package/src/windows/guidance.ts +0 -21
  266. package/src/windows/model-contract.test.ts +0 -37
  267. package/src/windows/protocol.ts +0 -27
  268. package/src/windows/text-contracts.test.ts +0 -14
  269. package/src/windows/window-typing.test.ts +0 -14
Binary file
@@ -1 +1 @@
1
- {"sha256":"9ba332bac617779b310c485ce575d53ae2d1e934d39a99f5726b49c5b85be079","protocolVersion":4,"architecture":"x64"}
1
+ {"protocolVersion":5,"sha256":"d3c083a243f8abe9ab1a09a16fc91657c7e5d127387f03a71d1a90c2cbfa41bd","architecture":"x64"}
@@ -0,0 +1,129 @@
1
+ import type { EventLogReader } from '@moxxy/sdk';
2
+ import { z } from 'zod';
3
+ import { type KeyPlatform } from '../contract/keys.js';
4
+ import type { ComputerAction } from '../contract/tools.js';
5
+ export declare const REQUEST_ACCESS_TOOL = "computer_request_access";
6
+ export declare const accessTiers: readonly ["read", "click", "full"];
7
+ export type AccessTier = (typeof accessTiers)[number];
8
+ export type AppCategory = 'browser' | 'terminal' | 'trading';
9
+ export declare function maxTier(...tiers: AccessTier[]): AccessTier;
10
+ /**
11
+ * What one approved `computer_request_access` call granted. It is the tool's
12
+ * own result, so the session log already records it for every client and the
13
+ * current access is a pure fold over that log.
14
+ */
15
+ export declare const accessGrantSchema: z.ZodObject<{
16
+ kind: z.ZodLiteral<"computer_access">;
17
+ granted: z.ZodArray<z.ZodObject<{
18
+ id: z.ZodString;
19
+ name: z.ZodString;
20
+ tier: z.ZodEnum<["read", "click", "full"]>;
21
+ }, "strict", z.ZodTypeAny, {
22
+ name: string;
23
+ id: string;
24
+ tier: "click" | "full" | "read";
25
+ }, {
26
+ name: string;
27
+ id: string;
28
+ tier: "click" | "full" | "read";
29
+ }>, "many">;
30
+ unresolved: z.ZodArray<z.ZodObject<{
31
+ app: z.ZodString;
32
+ reason: z.ZodEnum<["not_found", "ambiguous"]>;
33
+ candidates: z.ZodOptional<z.ZodArray<z.ZodObject<{
34
+ id: z.ZodString;
35
+ name: z.ZodString;
36
+ }, "strict", z.ZodTypeAny, {
37
+ name: string;
38
+ id: string;
39
+ }, {
40
+ name: string;
41
+ id: string;
42
+ }>, "many">>;
43
+ }, "strict", z.ZodTypeAny, {
44
+ reason: "ambiguous" | "not_found";
45
+ app: string;
46
+ candidates?: {
47
+ name: string;
48
+ id: string;
49
+ }[] | undefined;
50
+ }, {
51
+ reason: "ambiguous" | "not_found";
52
+ app: string;
53
+ candidates?: {
54
+ name: string;
55
+ id: string;
56
+ }[] | undefined;
57
+ }>, "many">;
58
+ clipboard_read: z.ZodBoolean;
59
+ clipboard_write: z.ZodBoolean;
60
+ system_key_combos: z.ZodBoolean;
61
+ }, "strict", z.ZodTypeAny, {
62
+ clipboard_read: boolean;
63
+ clipboard_write: boolean;
64
+ system_key_combos: boolean;
65
+ kind: "computer_access";
66
+ granted: {
67
+ name: string;
68
+ id: string;
69
+ tier: "click" | "full" | "read";
70
+ }[];
71
+ unresolved: {
72
+ reason: "ambiguous" | "not_found";
73
+ app: string;
74
+ candidates?: {
75
+ name: string;
76
+ id: string;
77
+ }[] | undefined;
78
+ }[];
79
+ }, {
80
+ clipboard_read: boolean;
81
+ clipboard_write: boolean;
82
+ system_key_combos: boolean;
83
+ kind: "computer_access";
84
+ granted: {
85
+ name: string;
86
+ id: string;
87
+ tier: "click" | "full" | "read";
88
+ }[];
89
+ unresolved: {
90
+ reason: "ambiguous" | "not_found";
91
+ app: string;
92
+ candidates?: {
93
+ name: string;
94
+ id: string;
95
+ }[] | undefined;
96
+ }[];
97
+ }>;
98
+ export type AccessGrant = z.infer<typeof accessGrantSchema>;
99
+ export type AppGrant = AccessGrant['granted'][number];
100
+ export interface AccessFlags {
101
+ readonly clipboardRead: boolean;
102
+ readonly clipboardWrite: boolean;
103
+ readonly systemKeyCombos: boolean;
104
+ }
105
+ export interface AccessState {
106
+ readonly apps: readonly AppGrant[];
107
+ readonly flags: AccessFlags;
108
+ }
109
+ /** Current access in a session: approved grants in log order, a later grant of an app replacing the earlier one. */
110
+ export declare function accessFromLog(log: EventLogReader): AccessState;
111
+ export declare const RUN_TOOL = "computer_run";
112
+ /**
113
+ * The apps of the runs a person approved as that very call, in log order: approving a run on an app is consent
114
+ * to the app. A run let through by a standing rule names nothing, since nobody saw which app it was for.
115
+ */
116
+ export declare function approvedThroughRun(log: EventLogReader): string[];
117
+ /** The grant for `app` (identifier or display name) if it allows `needed`. */
118
+ export declare function checkAccess(access: AccessState, app: string, needed: AccessTier): AppGrant;
119
+ /** Lowest grant level that allows a step: reading, a plain left click or scroll, or full control. */
120
+ export declare function requiredTier(step: ComputerAction): AccessTier;
121
+ /** Refuse system chords and clipboard chords the conversation has not been granted. */
122
+ export declare function checkKeys(step: ComputerAction, flags: AccessFlags, platform: KeyPlatform): void;
123
+ export declare function categorize(app: {
124
+ readonly id: string;
125
+ readonly name: string;
126
+ }): AppCategory | null;
127
+ /** Browsers and trading apps are read-only and terminals click-only unless the user approves full access. */
128
+ export declare function defaultTier(category: AppCategory | null): AccessTier;
129
+ //# sourceMappingURL=access.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access.d.ts","sourceRoot":"","sources":["../../src/backend/access.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAsD,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAE3G,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,eAAO,MAAM,mBAAmB,4BAA4B,CAAC;AAE7D,eAAO,MAAM,WAAW,oCAAqC,CAAC;AAC9D,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AACtD,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;AAI7D,wBAAgB,OAAO,CAAC,GAAG,KAAK,EAAE,UAAU,EAAE,GAAG,UAAU,CAE1D;AAED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWnB,CAAC;AACZ,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC5D,MAAM,MAAM,QAAQ,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtD,MAAM,WAAW,WAAW;IAAG,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAA;CAAE;AACrI,MAAM,WAAW,WAAW;IAAG,QAAQ,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAA;CAAE;AAEhG,oHAAoH;AACpH,wBAAgB,aAAa,CAAC,GAAG,EAAE,cAAc,GAAG,WAAW,CAe9D;AAED,eAAO,MAAM,QAAQ,iBAAiB,CAAC;AAEvC;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,EAAE,CAShE;AAED,8EAA8E;AAC9E,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,QAAQ,CAa1F;AAED,qGAAqG;AACrG,wBAAgB,YAAY,CAAC,IAAI,EAAE,cAAc,GAAG,UAAU,CAM7D;AAED,uFAAuF;AACvF,wBAAgB,SAAS,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,GAAG,IAAI,CAQ/F;AA0CD,wBAAgB,UAAU,CAAC,GAAG,EAAE;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,WAAW,GAAG,IAAI,CAQlG;AAED,6GAA6G;AAC7G,wBAAgB,WAAW,CAAC,QAAQ,EAAE,WAAW,GAAG,IAAI,GAAG,UAAU,CAIpE"}
@@ -0,0 +1,158 @@
1
+ import { z } from 'zod';
2
+ import { clipboardFlagsFor, isSystemKeyCombo, parseKeyCombo } from '../contract/keys.js';
3
+ import { ComputerUseError } from '../contract/outcome.js';
4
+ export const REQUEST_ACCESS_TOOL = 'computer_request_access';
5
+ export const accessTiers = ['read', 'click', 'full'];
6
+ const rank = (tier) => accessTiers.indexOf(tier);
7
+ export function maxTier(...tiers) {
8
+ return tiers.reduce((highest, tier) => (rank(tier) > rank(highest) ? tier : highest), 'read');
9
+ }
10
+ /**
11
+ * What one approved `computer_request_access` call granted. It is the tool's
12
+ * own result, so the session log already records it for every client and the
13
+ * current access is a pure fold over that log.
14
+ */
15
+ export const accessGrantSchema = z.object({
16
+ kind: z.literal('computer_access'),
17
+ granted: z.array(z.object({ id: z.string().min(1).max(512), name: z.string().max(512), tier: z.enum(accessTiers) }).strict()).max(32),
18
+ unresolved: z.array(z.object({
19
+ app: z.string().max(512),
20
+ reason: z.enum(['not_found', 'ambiguous']),
21
+ candidates: z.array(z.object({ id: z.string().max(512), name: z.string().max(512) }).strict()).max(16).optional(),
22
+ }).strict()).max(32),
23
+ clipboard_read: z.boolean(),
24
+ clipboard_write: z.boolean(),
25
+ system_key_combos: z.boolean(),
26
+ }).strict();
27
+ /** Current access in a session: approved grants in log order, a later grant of an app replacing the earlier one. */
28
+ export function accessFromLog(log) {
29
+ const requested = new Set(log.ofType('tool_call_requested').filter((event) => event.name === REQUEST_ACCESS_TOOL).map((event) => event.callId));
30
+ const approved = new Set(log.ofType('tool_call_approved').map((event) => event.callId));
31
+ const apps = new Map();
32
+ const flags = { clipboardRead: false, clipboardWrite: false, systemKeyCombos: false };
33
+ for (const result of log.ofType('tool_result')) {
34
+ if (!result.ok || !requested.has(result.callId) || !approved.has(result.callId))
35
+ continue;
36
+ const grant = accessGrantSchema.safeParse(result.output);
37
+ if (!grant.success)
38
+ continue;
39
+ for (const app of grant.data.granted)
40
+ apps.set(app.id, app);
41
+ flags.clipboardRead ||= grant.data.clipboard_read;
42
+ flags.clipboardWrite ||= grant.data.clipboard_write;
43
+ flags.systemKeyCombos ||= grant.data.system_key_combos;
44
+ }
45
+ return { apps: [...apps.values()], flags };
46
+ }
47
+ export const RUN_TOOL = 'computer_run';
48
+ /**
49
+ * The apps of the runs a person approved as that very call, in log order: approving a run on an app is consent
50
+ * to the app. A run let through by a standing rule names nothing, since nobody saw which app it was for.
51
+ */
52
+ export function approvedThroughRun(log) {
53
+ const decided = new Set(log.ofType('tool_call_approved').filter((event) => event.decidedNow === true).map((event) => event.callId));
54
+ const names = new Set();
55
+ for (const event of log.ofType('tool_call_requested')) {
56
+ if (event.name !== RUN_TOOL || !decided.has(event.callId))
57
+ continue;
58
+ const app = event.input?.app;
59
+ if (typeof app === 'string' && app.length > 0)
60
+ names.add(app);
61
+ }
62
+ return [...names];
63
+ }
64
+ /** The grant for `app` (identifier or display name) if it allows `needed`. */
65
+ export function checkAccess(access, app, needed) {
66
+ const wanted = app.toLowerCase();
67
+ const byId = access.apps.find((grant) => grant.id.toLowerCase() === wanted);
68
+ const byName = access.apps.filter((grant) => grant.name.toLowerCase() === wanted);
69
+ if (!byId && byName.length > 1) {
70
+ throw new ComputerUseError('ambiguous_app', `Several granted apps are named "${app}": ${byName.map((grant) => grant.id).join(', ')}`);
71
+ }
72
+ const grant = byId ?? byName[0];
73
+ if (!grant)
74
+ throw new ComputerUseError('app_not_allowed', `"${app}" is not granted in this conversation`);
75
+ if (rank(grant.tier) < rank(needed)) {
76
+ throw new ComputerUseError('tier_insufficient', `${grant.name} is granted at the "${grant.tier}" level; this action needs "${needed}"`);
77
+ }
78
+ return grant;
79
+ }
80
+ /** Lowest grant level that allows a step: reading, a plain left click or scroll, or full control. */
81
+ export function requiredTier(step) {
82
+ switch (step.action) {
83
+ case 'scroll': return 'click';
84
+ case 'click': return step.mouse_button === 'left' && step.modifiers === undefined ? 'click' : 'full';
85
+ default: return 'full';
86
+ }
87
+ }
88
+ /** Refuse system chords and clipboard chords the conversation has not been granted. */
89
+ export function checkKeys(step, flags, platform) {
90
+ if (step.action !== 'press_key')
91
+ return;
92
+ const combo = parseKeyCombo(step.key);
93
+ if (isSystemKeyCombo(combo, platform) && !flags.systemKeyCombos) {
94
+ throw new ComputerUseError('system_key_combo', `"${step.key}" acts on the whole system`);
95
+ }
96
+ const missing = clipboardFlagsFor(combo).filter((flag) => !flags[flag]);
97
+ if (missing.length > 0)
98
+ throw new ComputerUseError('clipboard_not_granted', `"${step.key}" needs ${missing.join(' and ')}`);
99
+ }
100
+ // Bundle identifiers / Windows executables / Linux desktop ids (a prefix matches its sub-identifiers) and display names
101
+ // (a name matches exactly or as the first words) of apps that get a restricted default level.
102
+ const KNOWN = {
103
+ browser: {
104
+ ids: [
105
+ 'com.apple.safari', 'com.apple.safaritechnologypreview', 'com.google.chrome', 'com.microsoft.edgemac', 'org.mozilla.firefox',
106
+ 'org.mozilla.nightly', 'com.brave.browser', 'com.operasoftware', 'com.vivaldi.vivaldi', 'company.thebrowser', 'org.chromium',
107
+ 'app.zen-browser', 'org.torproject.torbrowser', 'com.duckduckgo.macos.browser', 'com.openai.atlas', 'ai.perplexity.comet',
108
+ 'com.kagi.kagimacos', 'google-chrome', 'chromium', 'chromium-browser', 'firefox', 'firefox-esr', 'brave-browser',
109
+ 'microsoft-edge', 'vivaldi-stable', 'org.gnome.epiphany', 'org.kde.falkon', 'chrome.exe', 'msedge.exe', 'firefox.exe', 'brave.exe', 'opera.exe', 'vivaldi.exe', 'arc.exe',
110
+ ],
111
+ names: [
112
+ 'safari', 'google chrome', 'chrome', 'chromium', 'firefox', 'microsoft edge', 'brave', 'brave browser', 'opera', 'vivaldi',
113
+ 'arc', 'dia', 'web', 'falkon', 'tor browser', 'duckduckgo', 'zen', 'zen browser', 'orion', 'atlas', 'comet',
114
+ ],
115
+ },
116
+ terminal: {
117
+ ids: [
118
+ 'com.apple.terminal', 'com.googlecode.iterm2', 'dev.warp', 'com.github.wez.wezterm', 'org.alacritty', 'io.alacritty',
119
+ 'net.kovidgoyal.kitty', 'co.zeit.hyper', 'com.mitchellh.ghostty', 'com.microsoft.vscode', 'com.vscodium',
120
+ 'com.todesktop.230313mzl4w4u92', 'com.exafunction.windsurf', 'dev.zed', 'com.jetbrains', 'com.google.android.studio',
121
+ 'com.sublimetext', 'org.vim.macvim', 'org.gnu.emacs', 'com.apple.dt.xcode', 'com.apple.scripteditor2', 'com.apple.automator',
122
+ 'com.apple.shortcuts', 'org.gnome.terminal', 'org.gnome.console', 'org.gnome.ptyxis', 'org.kde.konsole', 'org.kde.kate',
123
+ 'org.xfce.terminal', 'xfce4-terminal', 'com.gexperts.tilix', 'xterm', 'code', 'codium', 'org.gnome.builder', 'windowsterminal.exe', 'powershell.exe', 'pwsh.exe', 'cmd.exe', 'code.exe', 'cursor.exe',
124
+ ],
125
+ names: [
126
+ 'terminal', 'windows terminal', 'gnome terminal', 'konsole', 'xterm', 'tilix', 'ptyxis', 'iterm', 'iterm2', 'warp', 'wezterm', 'alacritty', 'kitty', 'hyper', 'ghostty',
127
+ 'visual studio code', 'code', 'cursor', 'windsurf', 'zed', 'intellij idea', 'pycharm', 'webstorm', 'clion', 'goland', 'rider',
128
+ 'android studio', 'xcode', 'sublime text', 'macvim', 'emacs', 'powershell', 'command prompt', 'script editor', 'automator', 'shortcuts',
129
+ ],
130
+ },
131
+ trading: {
132
+ ids: ['com.webull', 'com.tastytrade', 'com.tradingview', 'com.fidelity.activetrader', 'com.binance', 'com.electron.exodus', 'com.ledger.live', 'io.trezor'],
133
+ names: [
134
+ 'robinhood', 'webull', 'thinkorswim', 'tradingview', 'tastytrade', 'interactive brokers', 'trader workstation', 'metatrader',
135
+ 'binance', 'coinbase', 'kraken', 'ledger live', 'trezor suite', 'exodus', 'electrum',
136
+ ],
137
+ },
138
+ };
139
+ export function categorize(app) {
140
+ const id = app.id.toLowerCase();
141
+ const name = app.name.toLowerCase().trim();
142
+ for (const [category, known] of Object.entries(KNOWN)) {
143
+ if (known.ids.some((prefix) => id === prefix || id.startsWith(`${prefix}.`)))
144
+ return category;
145
+ if (known.names.some((word) => name === word || name.startsWith(`${word} `)))
146
+ return category;
147
+ }
148
+ return null;
149
+ }
150
+ /** Browsers and trading apps are read-only and terminals click-only unless the user approves full access. */
151
+ export function defaultTier(category) {
152
+ if (category === 'browser' || category === 'trading')
153
+ return 'read';
154
+ if (category === 'terminal')
155
+ return 'click';
156
+ return 'full';
157
+ }
158
+ //# sourceMappingURL=access.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access.js","sourceRoot":"","sources":["../../src/backend/access.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /** What the model should know about one family of apps before it drives them. */
2
+ export interface AppHint {
3
+ /** Lower-case bundle identifiers, app ids or names this hint is for; a versioned identifier or name matches its base. */
4
+ readonly apps: readonly string[];
5
+ readonly text: string;
6
+ }
7
+ /** Each file is also a regular skill; `apps` in its frontmatter says whose hint it is. */
8
+ export declare const appHintsDirectory: string;
9
+ export declare function loadAppHints(directory?: string): AppHint[];
10
+ export declare function hintFor(hints: ReadonlyArray<AppHint>, app: {
11
+ id: string;
12
+ name: string;
13
+ }): string | undefined;
14
+ //# sourceMappingURL=app-hints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-hints.d.ts","sourceRoot":"","sources":["../../src/backend/app-hints.ts"],"names":[],"mappings":"AAMA,iFAAiF;AACjF,MAAM,WAAW,OAAO;IACtB,yHAAyH;IACzH,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,0FAA0F;AAC1F,eAAO,MAAM,iBAAiB,QAAwE,CAAC;AAIvG,wBAAgB,YAAY,CAAC,SAAS,GAAE,MAA0B,GAAG,OAAO,EAAE,CAa7E;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,GAAG,SAAS,CAK5G"}
@@ -0,0 +1,30 @@
1
+ import { readdirSync, readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { parseFrontmatterFile } from '@moxxy/sdk';
5
+ import { z } from 'zod';
6
+ /** Each file is also a regular skill; `apps` in its frontmatter says whose hint it is. */
7
+ export const appHintsDirectory = fileURLToPath(new URL('../../skills/computer-apps', import.meta.url));
8
+ const appsSchema = z.object({ apps: z.array(z.string().min(1)).min(1) });
9
+ export function loadAppHints(directory = appHintsDirectory) {
10
+ let files;
11
+ try {
12
+ files = readdirSync(directory).filter((file) => file.endsWith('.md')).sort();
13
+ }
14
+ catch {
15
+ return [];
16
+ }
17
+ return files.flatMap((file) => {
18
+ const { frontmatter, body } = parseFrontmatterFile(readFileSync(join(directory, file), 'utf8'));
19
+ const parsed = appsSchema.safeParse(frontmatter);
20
+ const text = body.trim();
21
+ return parsed.success && text ? [{ apps: parsed.data.apps.map((app) => app.toLowerCase()), text }] : [];
22
+ });
23
+ }
24
+ export function hintFor(hints, app) {
25
+ const keys = [app.id.toLowerCase(), app.name.toLowerCase()];
26
+ // "com.adobe.PremierePro.25" and "Adobe Premiere Pro 2025" are still Premiere Pro.
27
+ const matches = (entry) => keys.some((key) => key === entry || key.startsWith(`${entry}.`) || key.startsWith(`${entry} `));
28
+ return hints.find((hint) => hint.apps.some(matches))?.text;
29
+ }
30
+ //# sourceMappingURL=app-hints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-hints.js","sourceRoot":"","sources":["../../src/backend/app-hints.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AASxB,0FAA0F;AAC1F,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,4BAA4B,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAEvG,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAEzE,MAAM,UAAU,YAAY,CAAC,YAAoB,iBAAiB;IAChE,IAAI,KAAe,CAAC;IACpB,IAAI,CAAC;QACH,KAAK,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QAC5B,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,oBAAoB,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QAChG,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACjD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QACzB,OAAO,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1G,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,KAA6B,EAAE,GAAiC;IACtF,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,WAAW,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAC5D,mFAAmF;IACnF,MAAM,OAAO,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,KAAK,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC;IACnI,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC;AAC7D,CAAC"}
@@ -0,0 +1,70 @@
1
+ import { type LifecycleHooks, type SurfaceDef, type ToolDef } from '@moxxy/sdk';
2
+ import { type KeyPlatform } from '../contract/keys.js';
3
+ import { type AskJev } from '@moxxy/jev';
4
+ import { RunMemory } from '../jev/memory.js';
5
+ import { type AppHint } from './app-hints.js';
6
+ import { PreviewController, type PreviewCodec } from '../preview/controller.js';
7
+ import { TurnControls } from './turn-controls.js';
8
+ /** Everything platform-specific the shared backend needs: which helper to start and which key rules apply. */
9
+ export interface PlatformProfile {
10
+ readonly platform: KeyPlatform;
11
+ readonly protocolVersion: number;
12
+ readonly helperPath: string;
13
+ readonly helperArgs: readonly string[];
14
+ readonly verifyHelper: () => Promise<void>;
15
+ readonly unavailableMessage: string;
16
+ readonly timeoutMs?: number;
17
+ /** What the helper's live preview can produce; JPEG frames only when absent. */
18
+ readonly previewCodecs?: readonly PreviewCodec[];
19
+ }
20
+ /** The Codex/Claude-style tool set on top of one disposable native helper per session turn. */
21
+ export declare class ComputerBackend {
22
+ private readonly profile;
23
+ private readonly hints;
24
+ /** Jev for a TypeSafe key; a seam so tests need no network. */
25
+ private readonly jev;
26
+ private readonly memory;
27
+ private readonly turns;
28
+ readonly controls: TurnControls;
29
+ /** The human's live picture of the app in use; frames never reach the model or the session log. */
30
+ readonly preview: PreviewController;
31
+ readonly hooks: LifecycleHooks;
32
+ constructor(profile: PlatformProfile, hints?: ReadonlyArray<AppHint>,
33
+ /** Jev for a TypeSafe key; a seam so tests need no network. */
34
+ jev?: (apiKey: string) => AskJev, memory?: RunMemory);
35
+ /** Per session, whether the last tool call found a TypeSafe key: without one, runs of steps are not offered. */
36
+ private readonly keyed;
37
+ /** Per session, the names apps were asked for under and the app each resolved to: the model keeps using its own name. */
38
+ private readonly asked;
39
+ /** Per session, the apps approved through a run, placed by the helper once: the name asked for → its grant, or null when it has none. */
40
+ private readonly reached;
41
+ private jevKey;
42
+ surfaces(): SurfaceDef[];
43
+ tools(): ToolDef[];
44
+ release(sessionId: string, turnId?: string): Promise<void>;
45
+ private readonly handlers;
46
+ private observe;
47
+ /**
48
+ * What the conversation may use: the grants of the access dialog, then the apps approved through a run at their
49
+ * default level. Auto-approve raises none of them: it skips the prompt for a request of full control, not the
50
+ * policy that request goes through.
51
+ */
52
+ private access;
53
+ /** The grant for `app`, which may be the name it was asked for under instead of the one it has on this system. */
54
+ private granted;
55
+ /** One action on an app, behind the grant's level and the key rules. */
56
+ private perform;
57
+ /** Several actions on one app in one helper request, each behind the grant's level and the key rules. */
58
+ private performAll;
59
+ private act;
60
+ /** What a run teaches: the element of every verified step, a memory that proved stale, and a route that reached its end. */
61
+ private learn;
62
+ /** After a run could not do a step, the element the model then uses the same way, with effect, is that step's element. */
63
+ private learnFromModel;
64
+ /** A delivered action that leaves the app looking the same twice in a row did not work: say so. */
65
+ private judge;
66
+ private present;
67
+ private call;
68
+ private turn;
69
+ }
70
+ //# sourceMappingURL=backend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../src/backend/backend.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,cAAc,EAAE,KAAK,UAAU,EAAoB,KAAK,OAAO,EAAwB,MAAM,YAAY,CAAC;AAGrJ,OAAO,EAAiB,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAKtE,OAAO,EAA4C,KAAK,MAAM,EAAE,MAAM,YAAY,CAAC;AAEnF,OAAO,EAAE,SAAS,EAAoE,MAAM,kBAAkB,CAAC;AAU/G,OAAO,EAAyB,KAAK,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAKrE,OAAO,EAAE,iBAAiB,EAAE,KAAK,YAAY,EAAsB,MAAM,0BAA0B,CAAC;AAEpG,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,8GAA8G;AAC9G,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,YAAY,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,gFAAgF;IAChF,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;CAClD;AAuDD,+FAA+F;AAC/F,qBAAa,eAAe;IASxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,+DAA+D;IAC/D,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAZzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA2B;IACjD,QAAQ,CAAC,QAAQ,eAAsB;IACvC,mGAAmG;IACnG,QAAQ,CAAC,OAAO,oBAA2B;IAE3C,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;gBAGZ,OAAO,EAAE,eAAe,EACxB,KAAK,GAAE,aAAa,CAAC,OAAO,CAAkB;IAC/D,+DAA+D;IAC9C,GAAG,GAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAqD,EAC9E,MAAM,GAAE,SAA8D;IAWzF,gHAAgH;IAChH,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA8B;IACpD,yHAAyH;IACzH,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA0C;IAEhE,yIAAyI;IACzI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmD;YAE7D,MAAM;IAQpB,QAAQ,IAAI,UAAU,EAAE;IAIxB,KAAK,IAAI,OAAO,EAAE;IAkBZ,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAehE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAwFvB;IAEF,OAAO,CAAC,OAAO;IAKf;;;;OAIG;YACW,MAAM;IAyBpB,kHAAkH;IAClH,OAAO,CAAC,OAAO;IAKf,wEAAwE;YAC1D,OAAO;IAarB,yGAAyG;YAC3F,UAAU;YAWV,GAAG;IAYjB,4HAA4H;YAC9G,KAAK;IAkBnB,0HAA0H;YAC5G,cAAc;IAa5B,mGAAmG;IACnG,OAAO,CAAC,KAAK;IAgBb,OAAO,CAAC,OAAO;YAiBD,IAAI;YAoBJ,IAAI;CAoDnB"}