@mseep/clawdcursor 1.5.5

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 (354) hide show
  1. package/CHANGELOG.md +2264 -0
  2. package/LICENSE +21 -0
  3. package/README.md +385 -0
  4. package/SECURITY.md +44 -0
  5. package/SKILL.md +503 -0
  6. package/dist/core/agent-loop/agent.d.ts +42 -0
  7. package/dist/core/agent-loop/agent.js +1023 -0
  8. package/dist/core/agent-loop/agent.js.map +1 -0
  9. package/dist/core/agent-loop/batch-tool.d.ts +25 -0
  10. package/dist/core/agent-loop/batch-tool.js +218 -0
  11. package/dist/core/agent-loop/batch-tool.js.map +1 -0
  12. package/dist/core/agent-loop/coord-scale.d.ts +72 -0
  13. package/dist/core/agent-loop/coord-scale.js +89 -0
  14. package/dist/core/agent-loop/coord-scale.js.map +1 -0
  15. package/dist/core/agent-loop/focus-guard.d.ts +24 -0
  16. package/dist/core/agent-loop/focus-guard.js +29 -0
  17. package/dist/core/agent-loop/focus-guard.js.map +1 -0
  18. package/dist/core/agent-loop/project-mcp.d.ts +97 -0
  19. package/dist/core/agent-loop/project-mcp.js +253 -0
  20. package/dist/core/agent-loop/project-mcp.js.map +1 -0
  21. package/dist/core/agent-loop/prompt.d.ts +45 -0
  22. package/dist/core/agent-loop/prompt.js +426 -0
  23. package/dist/core/agent-loop/prompt.js.map +1 -0
  24. package/dist/core/agent-loop/tool-meta.d.ts +93 -0
  25. package/dist/core/agent-loop/tool-meta.js +651 -0
  26. package/dist/core/agent-loop/tool-meta.js.map +1 -0
  27. package/dist/core/agent-loop/tools.d.ts +38 -0
  28. package/dist/core/agent-loop/tools.js +2134 -0
  29. package/dist/core/agent-loop/tools.js.map +1 -0
  30. package/dist/core/agent-loop/types.d.ts +170 -0
  31. package/dist/core/agent-loop/types.js +12 -0
  32. package/dist/core/agent-loop/types.js.map +1 -0
  33. package/dist/core/agent.d.ts +51 -0
  34. package/dist/core/agent.js +245 -0
  35. package/dist/core/agent.js.map +1 -0
  36. package/dist/core/app-categories.d.ts +67 -0
  37. package/dist/core/app-categories.js +108 -0
  38. package/dist/core/app-categories.js.map +1 -0
  39. package/dist/core/banner.d.ts +70 -0
  40. package/dist/core/banner.js +245 -0
  41. package/dist/core/banner.js.map +1 -0
  42. package/dist/core/classify/capability.d.ts +45 -0
  43. package/dist/core/classify/capability.js +78 -0
  44. package/dist/core/classify/capability.js.map +1 -0
  45. package/dist/core/decompose/llm-decomposer.d.ts +35 -0
  46. package/dist/core/decompose/llm-decomposer.js +156 -0
  47. package/dist/core/decompose/llm-decomposer.js.map +1 -0
  48. package/dist/core/decompose/parser.d.ts +27 -0
  49. package/dist/core/decompose/parser.js +101 -0
  50. package/dist/core/decompose/parser.js.map +1 -0
  51. package/dist/core/observability/correlation.d.ts +19 -0
  52. package/dist/core/observability/correlation.js +36 -0
  53. package/dist/core/observability/correlation.js.map +1 -0
  54. package/dist/core/observability/cost-meter.d.ts +51 -0
  55. package/dist/core/observability/cost-meter.js +134 -0
  56. package/dist/core/observability/cost-meter.js.map +1 -0
  57. package/dist/core/observability/logger.d.ts +61 -0
  58. package/dist/core/observability/logger.js +550 -0
  59. package/dist/core/observability/logger.js.map +1 -0
  60. package/dist/core/router/aliases.d.ts +50 -0
  61. package/dist/core/router/aliases.js +104 -0
  62. package/dist/core/router/aliases.js.map +1 -0
  63. package/dist/core/router/normalize.d.ts +41 -0
  64. package/dist/core/router/normalize.js +80 -0
  65. package/dist/core/router/normalize.js.map +1 -0
  66. package/dist/core/safety.d.ts +126 -0
  67. package/dist/core/safety.js +568 -0
  68. package/dist/core/safety.js.map +1 -0
  69. package/dist/core/sense/a11y-resolver.d.ts +73 -0
  70. package/dist/core/sense/a11y-resolver.js +76 -0
  71. package/dist/core/sense/a11y-resolver.js.map +1 -0
  72. package/dist/core/sense/fingerprint.d.ts +41 -0
  73. package/dist/core/sense/fingerprint.js +123 -0
  74. package/dist/core/sense/fingerprint.js.map +1 -0
  75. package/dist/core/sense/rank.d.ts +70 -0
  76. package/dist/core/sense/rank.js +192 -0
  77. package/dist/core/sense/rank.js.map +1 -0
  78. package/dist/core/sense/reactive-check.d.ts +40 -0
  79. package/dist/core/sense/reactive-check.js +48 -0
  80. package/dist/core/sense/reactive-check.js.map +1 -0
  81. package/dist/core/sense/snapshot.d.ts +19 -0
  82. package/dist/core/sense/snapshot.js +100 -0
  83. package/dist/core/sense/snapshot.js.map +1 -0
  84. package/dist/core/sense/types.d.ts +66 -0
  85. package/dist/core/sense/types.js +9 -0
  86. package/dist/core/sense/types.js.map +1 -0
  87. package/dist/core/sense/ui-map-anchors.d.ts +7 -0
  88. package/dist/core/sense/ui-map-anchors.js +24 -0
  89. package/dist/core/sense/ui-map-anchors.js.map +1 -0
  90. package/dist/core/sense/ui-map-elements.d.ts +5 -0
  91. package/dist/core/sense/ui-map-elements.js +33 -0
  92. package/dist/core/sense/ui-map-elements.js.map +1 -0
  93. package/dist/core/sense/ui-map-find.d.ts +56 -0
  94. package/dist/core/sense/ui-map-find.js +153 -0
  95. package/dist/core/sense/ui-map-find.js.map +1 -0
  96. package/dist/core/sense/ui-map-fuse.d.ts +4 -0
  97. package/dist/core/sense/ui-map-fuse.js +44 -0
  98. package/dist/core/sense/ui-map-fuse.js.map +1 -0
  99. package/dist/core/sense/ui-map-geom.d.ts +3 -0
  100. package/dist/core/sense/ui-map-geom.js +16 -0
  101. package/dist/core/sense/ui-map-geom.js.map +1 -0
  102. package/dist/core/sense/ui-map-holder.d.ts +58 -0
  103. package/dist/core/sense/ui-map-holder.js +87 -0
  104. package/dist/core/sense/ui-map-holder.js.map +1 -0
  105. package/dist/core/sense/ui-map-normalize.d.ts +19 -0
  106. package/dist/core/sense/ui-map-normalize.js +65 -0
  107. package/dist/core/sense/ui-map-normalize.js.map +1 -0
  108. package/dist/core/sense/ui-map-render.d.ts +4 -0
  109. package/dist/core/sense/ui-map-render.js +34 -0
  110. package/dist/core/sense/ui-map-render.js.map +1 -0
  111. package/dist/core/sense/ui-map-resolve.d.ts +41 -0
  112. package/dist/core/sense/ui-map-resolve.js +59 -0
  113. package/dist/core/sense/ui-map-resolve.js.map +1 -0
  114. package/dist/core/sense/ui-map-types.d.ts +66 -0
  115. package/dist/core/sense/ui-map-types.js +11 -0
  116. package/dist/core/sense/ui-map-types.js.map +1 -0
  117. package/dist/core/sense/ui-map.d.ts +29 -0
  118. package/dist/core/sense/ui-map.js +113 -0
  119. package/dist/core/sense/ui-map.js.map +1 -0
  120. package/dist/core/verify/assertions.d.ts +132 -0
  121. package/dist/core/verify/assertions.js +284 -0
  122. package/dist/core/verify/assertions.js.map +1 -0
  123. package/dist/index.d.ts +21 -0
  124. package/dist/index.js +24 -0
  125. package/dist/index.js.map +1 -0
  126. package/dist/llm/browser-config.d.ts +36 -0
  127. package/dist/llm/browser-config.js +83 -0
  128. package/dist/llm/browser-config.js.map +1 -0
  129. package/dist/llm/client.d.ts +268 -0
  130. package/dist/llm/client.js +1094 -0
  131. package/dist/llm/client.js.map +1 -0
  132. package/dist/llm/config.d.ts +79 -0
  133. package/dist/llm/config.js +375 -0
  134. package/dist/llm/config.js.map +1 -0
  135. package/dist/llm/credentials.d.ts +35 -0
  136. package/dist/llm/credentials.js +491 -0
  137. package/dist/llm/credentials.js.map +1 -0
  138. package/dist/llm/external-creds.d.ts +42 -0
  139. package/dist/llm/external-creds.js +169 -0
  140. package/dist/llm/external-creds.js.map +1 -0
  141. package/dist/llm/providers.d.ts +123 -0
  142. package/dist/llm/providers.js +717 -0
  143. package/dist/llm/providers.js.map +1 -0
  144. package/dist/paths.d.ts +31 -0
  145. package/dist/paths.js +147 -0
  146. package/dist/paths.js.map +1 -0
  147. package/dist/platform/accessibility.d.ts +139 -0
  148. package/dist/platform/accessibility.js +670 -0
  149. package/dist/platform/accessibility.js.map +1 -0
  150. package/dist/platform/cdp-driver.d.ts +318 -0
  151. package/dist/platform/cdp-driver.js +1179 -0
  152. package/dist/platform/cdp-driver.js.map +1 -0
  153. package/dist/platform/index.d.ts +11 -0
  154. package/dist/platform/index.js +69 -0
  155. package/dist/platform/index.js.map +1 -0
  156. package/dist/platform/keys.d.ts +17 -0
  157. package/dist/platform/keys.js +129 -0
  158. package/dist/platform/keys.js.map +1 -0
  159. package/dist/platform/launch-poll.d.ts +101 -0
  160. package/dist/platform/launch-poll.js +177 -0
  161. package/dist/platform/launch-poll.js.map +1 -0
  162. package/dist/platform/linux.d.ts +173 -0
  163. package/dist/platform/linux.js +1253 -0
  164. package/dist/platform/linux.js.map +1 -0
  165. package/dist/platform/macos.d.ts +136 -0
  166. package/dist/platform/macos.js +976 -0
  167. package/dist/platform/macos.js.map +1 -0
  168. package/dist/platform/native-desktop.d.ts +145 -0
  169. package/dist/platform/native-desktop.js +936 -0
  170. package/dist/platform/native-desktop.js.map +1 -0
  171. package/dist/platform/native-helper.d.ts +130 -0
  172. package/dist/platform/native-helper.js +592 -0
  173. package/dist/platform/native-helper.js.map +1 -0
  174. package/dist/platform/ocr-engine.d.ts +78 -0
  175. package/dist/platform/ocr-engine.js +363 -0
  176. package/dist/platform/ocr-engine.js.map +1 -0
  177. package/dist/platform/ps-runner.d.ts +28 -0
  178. package/dist/platform/ps-runner.js +228 -0
  179. package/dist/platform/ps-runner.js.map +1 -0
  180. package/dist/platform/types.d.ts +397 -0
  181. package/dist/platform/types.js +15 -0
  182. package/dist/platform/types.js.map +1 -0
  183. package/dist/platform/uri-handler.d.ts +75 -0
  184. package/dist/platform/uri-handler.js +273 -0
  185. package/dist/platform/uri-handler.js.map +1 -0
  186. package/dist/platform/wayland-backend.d.ts +53 -0
  187. package/dist/platform/wayland-backend.js +348 -0
  188. package/dist/platform/wayland-backend.js.map +1 -0
  189. package/dist/platform/windows.d.ts +232 -0
  190. package/dist/platform/windows.js +1210 -0
  191. package/dist/platform/windows.js.map +1 -0
  192. package/dist/postbuild.d.ts +10 -0
  193. package/dist/postbuild.js +98 -0
  194. package/dist/postbuild.js.map +1 -0
  195. package/dist/schema/snapshot.d.ts +33 -0
  196. package/dist/schema/snapshot.js +90 -0
  197. package/dist/schema/snapshot.js.map +1 -0
  198. package/dist/shortcuts.d.ts +30 -0
  199. package/dist/shortcuts.js +261 -0
  200. package/dist/shortcuts.js.map +1 -0
  201. package/dist/surface/cli.d.ts +7 -0
  202. package/dist/surface/cli.js +1556 -0
  203. package/dist/surface/cli.js.map +1 -0
  204. package/dist/surface/dashboard.d.ts +8 -0
  205. package/dist/surface/dashboard.js +1193 -0
  206. package/dist/surface/dashboard.js.map +1 -0
  207. package/dist/surface/doctor.d.ts +29 -0
  208. package/dist/surface/doctor.js +1514 -0
  209. package/dist/surface/doctor.js.map +1 -0
  210. package/dist/surface/format.d.ts +10 -0
  211. package/dist/surface/format.js +37 -0
  212. package/dist/surface/format.js.map +1 -0
  213. package/dist/surface/http-utility.d.ts +65 -0
  214. package/dist/surface/http-utility.js +336 -0
  215. package/dist/surface/http-utility.js.map +1 -0
  216. package/dist/surface/mcp-server.d.ts +91 -0
  217. package/dist/surface/mcp-server.js +280 -0
  218. package/dist/surface/mcp-server.js.map +1 -0
  219. package/dist/surface/onboarding.d.ts +15 -0
  220. package/dist/surface/onboarding.js +184 -0
  221. package/dist/surface/onboarding.js.map +1 -0
  222. package/dist/surface/pidfile.d.ts +79 -0
  223. package/dist/surface/pidfile.js +263 -0
  224. package/dist/surface/pidfile.js.map +1 -0
  225. package/dist/surface/readiness.d.ts +45 -0
  226. package/dist/surface/readiness.js +230 -0
  227. package/dist/surface/readiness.js.map +1 -0
  228. package/dist/surface/report.d.ts +68 -0
  229. package/dist/surface/report.js +341 -0
  230. package/dist/surface/report.js.map +1 -0
  231. package/dist/surface/skill-register.d.ts +14 -0
  232. package/dist/surface/skill-register.js +150 -0
  233. package/dist/surface/skill-register.js.map +1 -0
  234. package/dist/surface/version.d.ts +6 -0
  235. package/dist/surface/version.js +27 -0
  236. package/dist/surface/version.js.map +1 -0
  237. package/dist/tools/a11y.d.ts +8 -0
  238. package/dist/tools/a11y.js +545 -0
  239. package/dist/tools/a11y.js.map +1 -0
  240. package/dist/tools/a11y_depth.d.ts +19 -0
  241. package/dist/tools/a11y_depth.js +455 -0
  242. package/dist/tools/a11y_depth.js.map +1 -0
  243. package/dist/tools/agent.d.ts +15 -0
  244. package/dist/tools/agent.js +248 -0
  245. package/dist/tools/agent.js.map +1 -0
  246. package/dist/tools/batch.d.ts +46 -0
  247. package/dist/tools/batch.js +230 -0
  248. package/dist/tools/batch.js.map +1 -0
  249. package/dist/tools/cdp.d.ts +8 -0
  250. package/dist/tools/cdp.js +233 -0
  251. package/dist/tools/cdp.js.map +1 -0
  252. package/dist/tools/compact.d.ts +63 -0
  253. package/dist/tools/compact.js +418 -0
  254. package/dist/tools/compact.js.map +1 -0
  255. package/dist/tools/cost-class.d.ts +38 -0
  256. package/dist/tools/cost-class.js +117 -0
  257. package/dist/tools/cost-class.js.map +1 -0
  258. package/dist/tools/desktop.d.ts +9 -0
  259. package/dist/tools/desktop.js +346 -0
  260. package/dist/tools/desktop.js.map +1 -0
  261. package/dist/tools/electron_bridge.d.ts +41 -0
  262. package/dist/tools/electron_bridge.js +261 -0
  263. package/dist/tools/electron_bridge.js.map +1 -0
  264. package/dist/tools/extras.d.ts +22 -0
  265. package/dist/tools/extras.js +942 -0
  266. package/dist/tools/extras.js.map +1 -0
  267. package/dist/tools/favorites.d.ts +13 -0
  268. package/dist/tools/favorites.js +137 -0
  269. package/dist/tools/favorites.js.map +1 -0
  270. package/dist/tools/introspection.d.ts +13 -0
  271. package/dist/tools/introspection.js +55 -0
  272. package/dist/tools/introspection.js.map +1 -0
  273. package/dist/tools/ocr.d.ts +8 -0
  274. package/dist/tools/ocr.js +66 -0
  275. package/dist/tools/ocr.js.map +1 -0
  276. package/dist/tools/orchestration.d.ts +7 -0
  277. package/dist/tools/orchestration.js +377 -0
  278. package/dist/tools/orchestration.js.map +1 -0
  279. package/dist/tools/playbooks/extract-compose.d.ts +22 -0
  280. package/dist/tools/playbooks/extract-compose.js +85 -0
  281. package/dist/tools/playbooks/extract-compose.js.map +1 -0
  282. package/dist/tools/playbooks/find-replace.d.ts +11 -0
  283. package/dist/tools/playbooks/find-replace.js +56 -0
  284. package/dist/tools/playbooks/find-replace.js.map +1 -0
  285. package/dist/tools/playbooks/index.d.ts +63 -0
  286. package/dist/tools/playbooks/index.js +70 -0
  287. package/dist/tools/playbooks/index.js.map +1 -0
  288. package/dist/tools/playbooks/keys-blocklist.d.ts +24 -0
  289. package/dist/tools/playbooks/keys-blocklist.js +89 -0
  290. package/dist/tools/playbooks/keys-blocklist.js.map +1 -0
  291. package/dist/tools/registry.d.ts +40 -0
  292. package/dist/tools/registry.js +560 -0
  293. package/dist/tools/registry.js.map +1 -0
  294. package/dist/tools/safety-gate.d.ts +16 -0
  295. package/dist/tools/safety-gate.js +70 -0
  296. package/dist/tools/safety-gate.js.map +1 -0
  297. package/dist/tools/scheduler.d.ts +76 -0
  298. package/dist/tools/scheduler.js +413 -0
  299. package/dist/tools/scheduler.js.map +1 -0
  300. package/dist/tools/shortcuts.d.ts +13 -0
  301. package/dist/tools/shortcuts.js +205 -0
  302. package/dist/tools/shortcuts.js.map +1 -0
  303. package/dist/tools/smart.d.ts +15 -0
  304. package/dist/tools/smart.js +785 -0
  305. package/dist/tools/smart.js.map +1 -0
  306. package/dist/tools/types.d.ts +174 -0
  307. package/dist/tools/types.js +67 -0
  308. package/dist/tools/types.js.map +1 -0
  309. package/dist/tools/window-text.d.ts +15 -0
  310. package/dist/tools/window-text.js +39 -0
  311. package/dist/tools/window-text.js.map +1 -0
  312. package/dist/types.d.ts +122 -0
  313. package/dist/types.js +41 -0
  314. package/dist/types.js.map +1 -0
  315. package/native/Package.swift +38 -0
  316. package/native/README.md +113 -0
  317. package/native/Sources/ClawdCursorHelper/main.swift +602 -0
  318. package/native/Sources/ClawdCursorHost/main.swift +182 -0
  319. package/native/Sources/PermissionCheck/main.swift +53 -0
  320. package/native/Sources/ScreenshotHelper/main.swift +219 -0
  321. package/native/build.sh +139 -0
  322. package/native/entitlements.plist +12 -0
  323. package/package.json +115 -0
  324. package/scripts/banner.ps1 +112 -0
  325. package/scripts/coord-accuracy.ps1 +140 -0
  326. package/scripts/coord-uwp.ps1 +80 -0
  327. package/scripts/edge-glow.ps1 +180 -0
  328. package/scripts/find-element.ps1 +198 -0
  329. package/scripts/get-foreground-window.ps1 +71 -0
  330. package/scripts/get-screen-context.ps1 +183 -0
  331. package/scripts/get-windows.ps1 +66 -0
  332. package/scripts/install-panic-hotkey.ps1 +46 -0
  333. package/scripts/interact-element.ps1 +431 -0
  334. package/scripts/invoke-element.ps1 +314 -0
  335. package/scripts/linux/atspi-bridge.py +356 -0
  336. package/scripts/linux/ocr-recognize.py +154 -0
  337. package/scripts/mac/_window-picker.jxa +163 -0
  338. package/scripts/mac/find-element.jxa +0 -0
  339. package/scripts/mac/find-element.sh +161 -0
  340. package/scripts/mac/focus-window.jxa +284 -0
  341. package/scripts/mac/get-focused-element.jxa +102 -0
  342. package/scripts/mac/get-foreground-window.jxa +173 -0
  343. package/scripts/mac/get-screen-context.jxa +197 -0
  344. package/scripts/mac/get-ui-tree.sh +141 -0
  345. package/scripts/mac/get-windows.jxa +117 -0
  346. package/scripts/mac/interact-element.sh +235 -0
  347. package/scripts/mac/invoke-element.jxa +408 -0
  348. package/scripts/mac/ocr-recognize.swift +124 -0
  349. package/scripts/ocr-recognize.ps1 +102 -0
  350. package/scripts/postinstall-native.js +48 -0
  351. package/scripts/ps-bridge.ps1 +830 -0
  352. package/scripts/smoke-mcp.ps1 +119 -0
  353. package/scripts/sync-version.ts +178 -0
  354. package/scripts/verify-install.js +81 -0
@@ -0,0 +1,348 @@
1
+ "use strict";
2
+ /**
3
+ * Wayland input routing via ydotool / wtype.
4
+ *
5
+ * The Linux adapter's nut-js path silently fails on most Wayland
6
+ * compositors because synthetic input events are blocked at the
7
+ * compositor layer unless injected through a privileged daemon.
8
+ * This module provides a minimal backend that routes mouse + keyboard
9
+ * operations through `ydotool` (requires `ydotoold` running with
10
+ * uinput access) or `wtype` (keyboard-only).
11
+ *
12
+ * Detection order at construction:
13
+ * 1. `ydotool` + socket reachable → preferred (mouse + keyboard)
14
+ * 2. `wtype` → keyboard-only fallback
15
+ * 3. neither → `none`; caller must return graceful error
16
+ *
17
+ * ydotool reference:
18
+ * mousemove --absolute <x> <y>
19
+ * click 0xC0 (left) 0xC1 (right) 0xC2 (middle)
20
+ * key <code>:1 (down) <code>:0 (up)
21
+ * type --delay 10 "text"
22
+ * mousemove -x <dx> -y <dy> (relative)
23
+ *
24
+ * All command construction goes through `execFile` (not shell), so
25
+ * there is NO shell interpolation of user text — clawdcursor typing
26
+ * a string with `$` or backticks is safe.
27
+ */
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.WaylandBackend = void 0;
30
+ const child_process_1 = require("child_process");
31
+ const util_1 = require("util");
32
+ const execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
33
+ const TIMEOUT_MS = 5_000;
34
+ /** Linux keycodes for the commonly-held modifiers + named keys we care about.
35
+ * Source: /usr/include/linux/input-event-codes.h
36
+ * Complete list isn't needed — covers the 90% case. Unknown keys fall back
37
+ * to `ydotool type` (which synthesizes the codepoint).
38
+ */
39
+ const LINUX_KEYCODES = {
40
+ // Modifiers
41
+ ctrl: 29, control: 29, leftctrl: 29,
42
+ rightctrl: 97,
43
+ shift: 42, leftshift: 42,
44
+ rightshift: 54,
45
+ alt: 56, option: 56, leftalt: 56,
46
+ rightalt: 100, altgr: 100,
47
+ super: 125, meta: 125, win: 125, cmd: 125,
48
+ rightsuper: 126,
49
+ // Navigation / editing
50
+ return: 28, enter: 28,
51
+ tab: 15,
52
+ escape: 1, esc: 1,
53
+ backspace: 14,
54
+ space: 57,
55
+ delete: 111,
56
+ home: 102,
57
+ end: 107,
58
+ pageup: 104,
59
+ pagedown: 109,
60
+ insert: 110,
61
+ capslock: 58,
62
+ // Arrows
63
+ left: 105,
64
+ right: 106,
65
+ up: 103,
66
+ down: 108,
67
+ // F-keys
68
+ f1: 59, f2: 60, f3: 61, f4: 62, f5: 63, f6: 64,
69
+ f7: 65, f8: 66, f9: 67, f10: 68, f11: 87, f12: 88,
70
+ };
71
+ /** Map an ASCII alphanumeric character to its Linux keycode. */
72
+ function charToKeycode(ch) {
73
+ if (ch.length !== 1)
74
+ return null;
75
+ const lower = ch.toLowerCase();
76
+ // a-z → 30..56 skipping a few (30=a, 48=b, 46=c, 32=d, 18=e, 33=f, 34=g,
77
+ // 35=h, 23=i, 36=j, 37=k, 38=l, 50=m, 49=n, 24=o, 25=p, 16=q, 19=r,
78
+ // 31=s, 20=t, 22=u, 47=v, 17=w, 45=x, 21=y, 44=z)
79
+ const lettersMap = {
80
+ a: 30, b: 48, c: 46, d: 32, e: 18, f: 33, g: 34, h: 35, i: 23, j: 36,
81
+ k: 37, l: 38, m: 50, n: 49, o: 24, p: 25, q: 16, r: 19, s: 31, t: 20,
82
+ u: 22, v: 47, w: 17, x: 45, y: 21, z: 44,
83
+ };
84
+ if (lower in lettersMap)
85
+ return lettersMap[lower];
86
+ // 0-9 → 10..19 (0=11, 1=2, 2=3, ..., 9=10) Wait — actually 1=2, 2=3, ..., 0=11.
87
+ const digitsMap = {
88
+ '1': 2, '2': 3, '3': 4, '4': 5, '5': 6, '6': 7, '7': 8, '8': 9, '9': 10, '0': 11,
89
+ };
90
+ if (lower in digitsMap)
91
+ return digitsMap[lower];
92
+ return null;
93
+ }
94
+ class WaylandBackend {
95
+ kind;
96
+ mod2code;
97
+ constructor(kind) {
98
+ this.kind = kind;
99
+ this.mod2code = {
100
+ mod: LINUX_KEYCODES.ctrl, // Linux "mod" resolves to Ctrl (same as clawdcursor's portable spec)
101
+ ctrl: LINUX_KEYCODES.ctrl,
102
+ control: LINUX_KEYCODES.ctrl,
103
+ shift: LINUX_KEYCODES.shift,
104
+ alt: LINUX_KEYCODES.alt,
105
+ option: LINUX_KEYCODES.alt,
106
+ super: LINUX_KEYCODES.super,
107
+ meta: LINUX_KEYCODES.super,
108
+ cmd: LINUX_KEYCODES.super,
109
+ command: LINUX_KEYCODES.super,
110
+ win: LINUX_KEYCODES.super,
111
+ };
112
+ }
113
+ static async detect(hasBinary) {
114
+ const [hasYd, hasWt] = await Promise.all([hasBinary('ydotool'), hasBinary('wtype')]);
115
+ if (hasYd)
116
+ return new WaylandBackend('ydotool');
117
+ if (hasWt)
118
+ return new WaylandBackend('wtype-keyboard-only');
119
+ return new WaylandBackend('none');
120
+ }
121
+ canMouse() { return this.kind === 'ydotool'; }
122
+ canKeyboard() { return this.kind === 'ydotool' || this.kind === 'wtype-keyboard-only'; }
123
+ // ── Mouse ───────────────────────────────────────────────────
124
+ async mouseMoveAbsolute(x, y) {
125
+ if (this.kind !== 'ydotool')
126
+ return;
127
+ await execFileAsync('ydotool', ['mousemove', '--absolute', '-x', String(x), '-y', String(y)], {
128
+ timeout: TIMEOUT_MS,
129
+ });
130
+ }
131
+ async mouseMoveRelative(dx, dy) {
132
+ if (this.kind !== 'ydotool')
133
+ return;
134
+ await execFileAsync('ydotool', ['mousemove', '-x', String(dx), '-y', String(dy)], {
135
+ timeout: TIMEOUT_MS,
136
+ });
137
+ }
138
+ /** `click` is a down+up in one ydotool call. For separate down/up, use mouseDown/mouseUp. */
139
+ async mouseClick(button = 'left', count = 1) {
140
+ if (this.kind !== 'ydotool')
141
+ return;
142
+ const code = button === 'left' ? '0xC0' : button === 'right' ? '0xC1' : '0xC2';
143
+ for (let i = 0; i < count; i++) {
144
+ await execFileAsync('ydotool', ['click', code], { timeout: TIMEOUT_MS });
145
+ if (i < count - 1)
146
+ await sleep(50);
147
+ }
148
+ }
149
+ async mouseDown(button = 'left') {
150
+ if (this.kind !== 'ydotool')
151
+ return;
152
+ // ydotool has `mousedown` on newer versions; fall back to the raw button
153
+ // code with :1 suffix which works on all versions.
154
+ const code = button === 'left' ? '0x110' : button === 'right' ? '0x111' : '0x112';
155
+ await execFileAsync('ydotool', ['key', `${code}:1`], { timeout: TIMEOUT_MS });
156
+ }
157
+ async mouseUp(button = 'left') {
158
+ if (this.kind !== 'ydotool')
159
+ return;
160
+ const code = button === 'left' ? '0x110' : button === 'right' ? '0x111' : '0x112';
161
+ await execFileAsync('ydotool', ['key', `${code}:0`], { timeout: TIMEOUT_MS });
162
+ }
163
+ async mouseScroll(direction, amount = 3) {
164
+ if (this.kind !== 'ydotool')
165
+ return;
166
+ // `ydotool mousemove --wheel` doesn't exist; use `ydotool scroll` if
167
+ // available, else fall back to button-code press (4/5 vertical, 6/7 horizontal).
168
+ try {
169
+ if (direction === 'up')
170
+ await execFileAsync('ydotool', ['scroll', String(-amount)], { timeout: TIMEOUT_MS });
171
+ else if (direction === 'down')
172
+ await execFileAsync('ydotool', ['scroll', String(amount)], { timeout: TIMEOUT_MS });
173
+ else {
174
+ // Horizontal: ydotool doesn't directly support; fall back to button codes.
175
+ const code = direction === 'left' ? '0x06' : '0x07';
176
+ for (let i = 0; i < amount; i++) {
177
+ await execFileAsync('ydotool', ['key', `${code}:1`, `${code}:0`], { timeout: TIMEOUT_MS });
178
+ }
179
+ }
180
+ }
181
+ catch {
182
+ // scroll subcmd not supported on this ydotool build — try button codes.
183
+ const code = direction === 'up' ? '0x04' :
184
+ direction === 'down' ? '0x05' :
185
+ direction === 'left' ? '0x06' : '0x07';
186
+ for (let i = 0; i < amount; i++) {
187
+ await execFileAsync('ydotool', ['key', `${code}:1`, `${code}:0`], { timeout: TIMEOUT_MS });
188
+ }
189
+ }
190
+ }
191
+ // ── Keyboard ────────────────────────────────────────────────
192
+ /**
193
+ * Press a key combo. On ydotool we map each component to a Linux
194
+ * keycode and emit paired down/up events. On wtype we use wtype's
195
+ * native combo syntax (e.g. `wtype -M ctrl -k s`).
196
+ */
197
+ async keyPress(combo) {
198
+ if (this.kind === 'none')
199
+ return;
200
+ // Special case: literal "+"
201
+ if (combo === '+') {
202
+ if (this.kind === 'ydotool') {
203
+ await execFileAsync('ydotool', ['type', '--', '+'], { timeout: TIMEOUT_MS });
204
+ }
205
+ else {
206
+ await execFileAsync('wtype', ['+'], { timeout: TIMEOUT_MS });
207
+ }
208
+ return;
209
+ }
210
+ const parts = combo.split('+').map(s => s.trim()).filter(Boolean);
211
+ if (parts.length === 0)
212
+ return;
213
+ if (this.kind === 'wtype-keyboard-only') {
214
+ // wtype: -M <mod> repeatable, then -k <keyname> or bare text.
215
+ const args = [];
216
+ const modsLower = parts.slice(0, -1).map(p => p.toLowerCase());
217
+ const key = parts[parts.length - 1];
218
+ for (const m of modsLower) {
219
+ const wm = wtypeModName(m);
220
+ if (wm) {
221
+ args.push('-M', wm);
222
+ }
223
+ }
224
+ // wtype named keys (Return, Tab, etc.) go via `-k`.
225
+ const wtypeKey = wtypeKeyName(key);
226
+ if (wtypeKey) {
227
+ args.push('-k', wtypeKey);
228
+ }
229
+ else if (key.length === 1) {
230
+ args.push(key);
231
+ }
232
+ else {
233
+ // Unknown key — best-effort type the text.
234
+ args.push(key);
235
+ }
236
+ await execFileAsync('wtype', args, { timeout: TIMEOUT_MS }).catch(() => { });
237
+ return;
238
+ }
239
+ // ydotool path: press all modifier codes (down), tap main key, release modifiers.
240
+ const modCodes = [];
241
+ for (let i = 0; i < parts.length - 1; i++) {
242
+ const code = this.mod2code[parts[i].toLowerCase()];
243
+ if (typeof code === 'number')
244
+ modCodes.push(code);
245
+ }
246
+ const mainName = parts[parts.length - 1];
247
+ const mainCode = this.keyToCode(mainName);
248
+ try {
249
+ // Press modifiers
250
+ for (const c of modCodes) {
251
+ await execFileAsync('ydotool', ['key', `${c}:1`], { timeout: TIMEOUT_MS });
252
+ }
253
+ if (mainCode !== null) {
254
+ await execFileAsync('ydotool', ['key', `${mainCode}:1`, `${mainCode}:0`], {
255
+ timeout: TIMEOUT_MS,
256
+ });
257
+ }
258
+ else if (mainName.length > 0) {
259
+ // No keycode mapping — type it as text (ydotool type handles the layout).
260
+ await execFileAsync('ydotool', ['type', '--', mainName], { timeout: TIMEOUT_MS });
261
+ }
262
+ }
263
+ finally {
264
+ // Release modifiers in reverse order
265
+ for (let i = modCodes.length - 1; i >= 0; i--) {
266
+ await execFileAsync('ydotool', ['key', `${modCodes[i]}:0`], { timeout: TIMEOUT_MS })
267
+ .catch(() => { });
268
+ }
269
+ }
270
+ }
271
+ async keyDown(key) {
272
+ if (this.kind !== 'ydotool')
273
+ return;
274
+ const code = this.keyToCode(key.toLowerCase());
275
+ if (code === null)
276
+ return;
277
+ await execFileAsync('ydotool', ['key', `${code}:1`], { timeout: TIMEOUT_MS });
278
+ }
279
+ async keyUp(key) {
280
+ if (this.kind !== 'ydotool')
281
+ return;
282
+ const code = this.keyToCode(key.toLowerCase());
283
+ if (code === null)
284
+ return;
285
+ await execFileAsync('ydotool', ['key', `${code}:0`], { timeout: TIMEOUT_MS });
286
+ }
287
+ async typeText(text) {
288
+ if (this.kind === 'none' || !text)
289
+ return;
290
+ if (this.kind === 'ydotool') {
291
+ // Small delay so fast apps don't drop chars.
292
+ await execFileAsync('ydotool', ['type', '--delay', '10', '--', text], {
293
+ timeout: TIMEOUT_MS + text.length * 15,
294
+ });
295
+ return;
296
+ }
297
+ // wtype: positional arg
298
+ await execFileAsync('wtype', ['--', text], {
299
+ timeout: TIMEOUT_MS + text.length * 15,
300
+ });
301
+ }
302
+ // ── Internals ───────────────────────────────────────────────
303
+ keyToCode(name) {
304
+ const low = name.toLowerCase();
305
+ if (low in LINUX_KEYCODES)
306
+ return LINUX_KEYCODES[low];
307
+ if (low in this.mod2code)
308
+ return this.mod2code[low];
309
+ const ch = charToKeycode(name);
310
+ if (ch !== null)
311
+ return ch;
312
+ return null;
313
+ }
314
+ }
315
+ exports.WaylandBackend = WaylandBackend;
316
+ function wtypeModName(m) {
317
+ if (m === 'ctrl' || m === 'control' || m === 'mod')
318
+ return 'ctrl';
319
+ if (m === 'shift')
320
+ return 'shift';
321
+ if (m === 'alt' || m === 'option')
322
+ return 'alt';
323
+ if (m === 'super' || m === 'cmd' || m === 'command' || m === 'meta' || m === 'win')
324
+ return 'logo';
325
+ return null;
326
+ }
327
+ function wtypeKeyName(k) {
328
+ const lo = k.toLowerCase();
329
+ const map = {
330
+ return: 'Return', enter: 'Return',
331
+ tab: 'Tab',
332
+ space: 'space',
333
+ escape: 'Escape', esc: 'Escape',
334
+ backspace: 'BackSpace',
335
+ delete: 'Delete',
336
+ home: 'Home', end: 'End',
337
+ pageup: 'Page_Up', pagedown: 'Page_Down',
338
+ insert: 'Insert',
339
+ left: 'Left', right: 'Right', up: 'Up', down: 'Down',
340
+ f1: 'F1', f2: 'F2', f3: 'F3', f4: 'F4', f5: 'F5', f6: 'F6',
341
+ f7: 'F7', f8: 'F8', f9: 'F9', f10: 'F10', f11: 'F11', f12: 'F12',
342
+ };
343
+ return map[lo] ?? null;
344
+ }
345
+ function sleep(ms) {
346
+ return new Promise(r => setTimeout(r, ms));
347
+ }
348
+ //# sourceMappingURL=wayland-backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wayland-backend.js","sourceRoot":"","sources":["../../src/platform/wayland-backend.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,232 @@
1
+ /**
2
+ * Windows PlatformAdapter — all Windows-specific code lives here.
3
+ *
4
+ * Strategy:
5
+ * - Mouse + keyboard: nut-js directly (no TCC blocking as on macOS)
6
+ * - Screenshot: nut-js screen.grab() — no special helper binary
7
+ * - Screen size + DPI: System.Windows.Forms.Screen via PowerShell for logical px,
8
+ * compared with nut-js physical px to derive dpiRatio
9
+ * - Windows + A11y: persistent PSRunner (../../ps-runner.ts) driving UI Automation
10
+ * - Clipboard: Get-Clipboard / Set-Clipboard via PowerShell
11
+ * - App launch: Start-Process via PowerShell
12
+ *
13
+ * Permissions: Windows has no TCC-style gate — returns all-true.
14
+ */
15
+ import type { PlatformAdapter, ScreenSize, ScreenshotResult, WindowInfo, UiElement, PermissionStatus, PortableKeyCombo, Display, InvokeAction, MouseButton, ScrollDirection, WaitForElementQuery, WindowState, FocusActivation } from './types';
16
+ export declare class WindowsAdapter implements PlatformAdapter {
17
+ readonly platform: "win32";
18
+ private screenSize;
19
+ init(): Promise<void>;
20
+ shutdown(): Promise<void>;
21
+ checkPermissions(): Promise<PermissionStatus>;
22
+ requestPermissions(): Promise<PermissionStatus>;
23
+ getScreenSize(): Promise<ScreenSize>;
24
+ listDisplays(): Promise<Display[]>;
25
+ screenshot(opts?: {
26
+ maxWidth?: number;
27
+ displayIndex?: number;
28
+ }): Promise<ScreenshotResult>;
29
+ screenshotRegion(x: number, y: number, w: number, h: number): Promise<ScreenshotResult>;
30
+ listWindows(): Promise<WindowInfo[]>;
31
+ getActiveWindow(): Promise<WindowInfo | null>;
32
+ focusWindow(query: {
33
+ processName?: string;
34
+ processId?: number;
35
+ title?: string;
36
+ }): Promise<boolean>;
37
+ maximizeWindow(): Promise<void>;
38
+ setWindowState(state: WindowState, query?: {
39
+ processName?: string;
40
+ processId?: number;
41
+ title?: string;
42
+ }): Promise<boolean>;
43
+ setWindowBounds(bounds: {
44
+ x?: number;
45
+ y?: number;
46
+ width?: number;
47
+ height?: number;
48
+ }, query?: {
49
+ processName?: string;
50
+ processId?: number;
51
+ title?: string;
52
+ }): Promise<boolean>;
53
+ /**
54
+ * Internal helper — resolve a focusWindow-style query to a single
55
+ * WindowInfo. Same precedence the public `focusWindow` uses.
56
+ */
57
+ private resolveWindow;
58
+ getUiTree(processId?: number): Promise<UiElement[]>;
59
+ findElements(query: {
60
+ name?: string;
61
+ controlType?: string;
62
+ processId?: number;
63
+ }): Promise<UiElement[]>;
64
+ getFocusedElement(): Promise<UiElement | null>;
65
+ invokeElement(query: {
66
+ name?: string;
67
+ controlType?: string;
68
+ processId?: number;
69
+ action?: InvokeAction;
70
+ value?: string;
71
+ }): Promise<{
72
+ success: boolean;
73
+ bounds?: {
74
+ x: number;
75
+ y: number;
76
+ width: number;
77
+ height: number;
78
+ };
79
+ data?: Record<string, unknown>;
80
+ }>;
81
+ waitForElement(query: WaitForElementQuery, timeoutMs: number): Promise<UiElement | null>;
82
+ /** Cursor cache for mouseMoveRelative — last known target. */
83
+ private lastCursor;
84
+ /**
85
+ * Ensure the window at (x, y) is the foreground window before clicking.
86
+ *
87
+ * Problem: On Windows, nut-js sends mouse input via SendInput which
88
+ * delivers to whatever window is topmost at those coordinates — not
89
+ * necessarily the foreground window. When a Save As dialog sits over a
90
+ * File Explorer window (or any background window), a click intended for
91
+ * the dialog's filename field can land on the Explorer window if the
92
+ * dialog's owning process lost foreground between the screenshot and the
93
+ * click (race) or if the click coords are slightly outside the dialog rect
94
+ * due to DPI-related rounding.
95
+ *
96
+ * Fix: use Win32 WindowFromPoint (via the warm psRunner bridge) to
97
+ * identify the window at the target coords. If it is not the current
98
+ * foreground window, call SetForegroundWindow to bring it forward before
99
+ * the click lands. Non-fatal — if the PS call fails we proceed anyway.
100
+ */
101
+ private ensureForegroundAtPoint;
102
+ private toNutButton;
103
+ mouseClick(x: number, y: number, opts?: {
104
+ button?: MouseButton;
105
+ count?: number;
106
+ }): Promise<FocusActivation | void>;
107
+ mouseMove(x: number, y: number): Promise<void>;
108
+ mouseMoveRelative(dx: number, dy: number): Promise<void>;
109
+ mouseDrag(x1: number, y1: number, x2: number, y2: number): Promise<void>;
110
+ mouseScroll(x: number, y: number, direction: ScrollDirection, amount?: number): Promise<void>;
111
+ mouseDown(button?: MouseButton): Promise<void>;
112
+ mouseUp(button?: MouseButton): Promise<void>;
113
+ typeText(text: string): Promise<void>;
114
+ keyPress(combo: PortableKeyCombo): Promise<void>;
115
+ keyDown(key: PortableKeyCombo): Promise<void>;
116
+ keyUp(key: PortableKeyCombo): Promise<void>;
117
+ readClipboard(): Promise<string>;
118
+ writeClipboard(text: string): Promise<void>;
119
+ /**
120
+ * Thin shim — delegates straight to `launchApp` with no alias resolution.
121
+ * The platform layer is alias-data-agnostic; alias resolution lives in
122
+ * the caller (the agent's `open_app` tool, the router's `handleOpenApp`).
123
+ * Callers that want UWP / executable / searchTerm hints must pass them
124
+ * via `launchApp` directly.
125
+ */
126
+ openApp(name: string, opts?: {
127
+ alwaysNewInstance?: boolean;
128
+ }): Promise<{
129
+ pid?: number;
130
+ title?: string;
131
+ }>;
132
+ launchApp(name: string, opts?: {
133
+ alwaysNewInstance?: boolean;
134
+ url?: string;
135
+ cwd?: string;
136
+ /**
137
+ * UWP AppsFolder ID, e.g. `Microsoft.WindowsCalculator_8wekyb3d8bbwe!App`.
138
+ * Launches via `explorer.exe shell:AppsFolder\<id>` which works for
139
+ * Store / UWP apps where `Start-Process -FilePath <exe>` silently fails.
140
+ * Takes precedence over `name` when provided.
141
+ */
142
+ uwpAppId?: string;
143
+ /**
144
+ * Human-friendly term for the Start-Menu-search fallback. See the
145
+ * `PlatformAdapter` interface doc for why this matters — typing the
146
+ * binary name in Start Menu can surface the wrong app.
147
+ */
148
+ searchTerm?: string;
149
+ /** Skip the Start-Menu search fallback; return {} if no window surfaces. */
150
+ noStartMenuFallback?: boolean;
151
+ }): Promise<{
152
+ pid?: number;
153
+ title?: string;
154
+ handle?: number | string;
155
+ }>;
156
+ /**
157
+ * Bring a freshly-launched window to the foreground. A detached spawn opens
158
+ * the app BEHIND the current foreground (Windows foreground-lock), so without
159
+ * this `open_app("calc")` left Calculator in the background and every
160
+ * subsequent focused-window op (read_screen, find_element) targeted the wrong
161
+ * window. The idempotency path already focuses; this gives fresh launches the
162
+ * same contract. Best-effort — never throws, the launch already succeeded.
163
+ */
164
+ private foregroundLaunched;
165
+ /**
166
+ * Last-resort launch via Windows' own Start Menu search. Works for any
167
+ * app the user can find by name in the Start Menu (apps, settings panes,
168
+ * UWP without a known AppsFolder ID, third-party Win32 binaries with an
169
+ * App Paths entry). The keyboard primitives we use here go through the
170
+ * adapter directly, NOT through the safety layer — this is internal
171
+ * platform logic, not an agent action.
172
+ *
173
+ * Tuned to the same cadence as the router's startMenuSearch helper.
174
+ */
175
+ private launchViaStartMenuSearch;
176
+ /**
177
+ * After a launch, wait for the new window to surface. Uses the shared
178
+ * `waitForLaunchedWindow` diff-and-poll helper so the budget is spent
179
+ * doing useful work (polling every 300ms) rather than a single fixed
180
+ * settle. Returns `{}` when the deadline elapses with no match — caller
181
+ * can interpret that as a real "this strategy didn't work" signal and
182
+ * try the next strategy.
183
+ *
184
+ * On Windows, neither the UWP shell:AppsFolder spawn nor the classic
185
+ * Start-Process spawn returns the eventual app's PID (we spawn explorer /
186
+ * powershell, not the target binary), so we don't pass `spawnPid`.
187
+ * The predicate matches by process name + title, same as the old
188
+ * single-shot logic — just polled.
189
+ */
190
+ private findLaunchedWindow;
191
+ /**
192
+ * v0.8.3 — check whether an app matching `name` or `uwpAppId` already has
193
+ * a visible top-level window. Used by `launchApp` to short-circuit when
194
+ * the user / agent asks to "open Outlook" but Outlook is already running.
195
+ *
196
+ * Match policy: case-insensitive process-name / title substring, which
197
+ * matches the same alias set the router uses. A `uwpAppId` like
198
+ * `Microsoft.WindowsCalculator_8wekyb3d8bbwe!App` is reduced to its App
199
+ * token (`App`, `Calculator`) and matched against window titles as a
200
+ * fallback.
201
+ *
202
+ * Returns `null` when no matching window is found — caller proceeds with
203
+ * a normal launch.
204
+ */
205
+ private findExistingAppWindow;
206
+ /**
207
+ * Same matching logic as `findExistingAppWindow` but takes an already-fetched
208
+ * window list. Lets `launchApp` reuse the snapshot it captures for the
209
+ * post-spawn diff-and-poll, avoiding a redundant PS-bridge round-trip.
210
+ */
211
+ private findExistingAppWindowIn;
212
+ /**
213
+ * PowerShell single-quoted string escape. Inside single quotes, the only
214
+ * special char is the single quote itself, which doubles to escape.
215
+ * This is the only safe way to pass a user-controlled string as a
216
+ * PowerShell argument.
217
+ */
218
+ private psQuote;
219
+ private normalizeWindow;
220
+ private normalizeElement;
221
+ /**
222
+ * Flatten the UIA tree into a single list, matching the macOS adapter's
223
+ * contract. Drops purely structural unnamed nodes to keep the list useful.
224
+ */
225
+ private flattenTree;
226
+ /**
227
+ * Map a portable key token to the nut-js Key enum (or 'TYPE_CHAR' for
228
+ * printable ASCII symbols that don't have a direct enum entry).
229
+ */
230
+ private mapKey;
231
+ private delay;
232
+ }