@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,198 @@
1
+ <#
2
+ .SYNOPSIS
3
+ Searches the UI tree for elements matching given criteria.
4
+ .PARAMETER Name
5
+ Match elements whose Name property contains this string (case-insensitive).
6
+ .PARAMETER AutomationId
7
+ Match elements whose AutomationId equals this string exactly.
8
+ .PARAMETER ControlType
9
+ Match elements whose ControlType ProgrammaticName contains this string
10
+ (e.g. "Button", "Edit", "MenuItem").
11
+ .PARAMETER ProcessId
12
+ If specified, only search within the window belonging to this process.
13
+ If omitted, searches all top-level windows.
14
+ .PARAMETER MaxResults
15
+ Maximum number of results to return (default 20).
16
+ #>
17
+ param(
18
+ [string]$Name = "",
19
+ [string]$AutomationId = "",
20
+ [string]$ControlType = "",
21
+ [int]$ProcessId = 0,
22
+ [int]$MaxResults = 20
23
+ )
24
+
25
+ try {
26
+ Add-Type -AssemblyName UIAutomationClient
27
+ Add-Type -AssemblyName UIAutomationTypes
28
+ } catch {
29
+ [Console]::Out.Write((@{ error = "Failed to load UI Automation assemblies: $($_.Exception.Message)" } | ConvertTo-Json -Compress))
30
+ exit 1
31
+ }
32
+
33
+ $ErrorActionPreference = 'Stop'
34
+
35
+ try {
36
+ $root = [System.Windows.Automation.AutomationElement]::RootElement
37
+
38
+ # Determine the search root
39
+ if ($ProcessId -gt 0) {
40
+ $procCondition = New-Object System.Windows.Automation.PropertyCondition(
41
+ [System.Windows.Automation.AutomationElement]::ProcessIdProperty,
42
+ $ProcessId
43
+ )
44
+ $searchRoot = $root.FindFirst(
45
+ [System.Windows.Automation.TreeScope]::Children,
46
+ $procCondition
47
+ )
48
+ if ($null -eq $searchRoot) {
49
+ [Console]::Out.Write((@{ error = "No window found for ProcessId $ProcessId" } | ConvertTo-Json -Compress))
50
+ exit 0
51
+ }
52
+ } else {
53
+ $searchRoot = $root
54
+ }
55
+
56
+ # Build UIA condition for FindAll
57
+ $conditions = @()
58
+
59
+ if ($AutomationId -ne "") {
60
+ $conditions += New-Object System.Windows.Automation.PropertyCondition(
61
+ [System.Windows.Automation.AutomationElement]::AutomationIdProperty,
62
+ $AutomationId
63
+ )
64
+ }
65
+
66
+ if ($ControlType -ne "") {
67
+ # Map common control type names to ControlType objects
68
+ $ctMap = @{
69
+ "Button" = [System.Windows.Automation.ControlType]::Button
70
+ "Calendar" = [System.Windows.Automation.ControlType]::Calendar
71
+ "CheckBox" = [System.Windows.Automation.ControlType]::CheckBox
72
+ "ComboBox" = [System.Windows.Automation.ControlType]::ComboBox
73
+ "Custom" = [System.Windows.Automation.ControlType]::Custom
74
+ "DataGrid" = [System.Windows.Automation.ControlType]::DataGrid
75
+ "DataItem" = [System.Windows.Automation.ControlType]::DataItem
76
+ "Document" = [System.Windows.Automation.ControlType]::Document
77
+ "Edit" = [System.Windows.Automation.ControlType]::Edit
78
+ "Group" = [System.Windows.Automation.ControlType]::Group
79
+ "Header" = [System.Windows.Automation.ControlType]::Header
80
+ "HeaderItem" = [System.Windows.Automation.ControlType]::HeaderItem
81
+ "Hyperlink" = [System.Windows.Automation.ControlType]::Hyperlink
82
+ "Image" = [System.Windows.Automation.ControlType]::Image
83
+ "List" = [System.Windows.Automation.ControlType]::List
84
+ "ListItem" = [System.Windows.Automation.ControlType]::ListItem
85
+ "Menu" = [System.Windows.Automation.ControlType]::Menu
86
+ "MenuBar" = [System.Windows.Automation.ControlType]::MenuBar
87
+ "MenuItem" = [System.Windows.Automation.ControlType]::MenuItem
88
+ "Pane" = [System.Windows.Automation.ControlType]::Pane
89
+ "ProgressBar" = [System.Windows.Automation.ControlType]::ProgressBar
90
+ "RadioButton" = [System.Windows.Automation.ControlType]::RadioButton
91
+ "ScrollBar" = [System.Windows.Automation.ControlType]::ScrollBar
92
+ "Separator" = [System.Windows.Automation.ControlType]::Separator
93
+ "Slider" = [System.Windows.Automation.ControlType]::Slider
94
+ "Spinner" = [System.Windows.Automation.ControlType]::Spinner
95
+ "SplitButton" = [System.Windows.Automation.ControlType]::SplitButton
96
+ "StatusBar" = [System.Windows.Automation.ControlType]::StatusBar
97
+ "Tab" = [System.Windows.Automation.ControlType]::Tab
98
+ "TabItem" = [System.Windows.Automation.ControlType]::TabItem
99
+ "Table" = [System.Windows.Automation.ControlType]::Table
100
+ "Text" = [System.Windows.Automation.ControlType]::Text
101
+ "Thumb" = [System.Windows.Automation.ControlType]::Thumb
102
+ "TitleBar" = [System.Windows.Automation.ControlType]::TitleBar
103
+ "ToolBar" = [System.Windows.Automation.ControlType]::ToolBar
104
+ "ToolTip" = [System.Windows.Automation.ControlType]::ToolTip
105
+ "Tree" = [System.Windows.Automation.ControlType]::Tree
106
+ "TreeItem" = [System.Windows.Automation.ControlType]::TreeItem
107
+ "Window" = [System.Windows.Automation.ControlType]::Window
108
+ }
109
+
110
+ if ($ctMap.ContainsKey($ControlType)) {
111
+ $conditions += New-Object System.Windows.Automation.PropertyCondition(
112
+ [System.Windows.Automation.AutomationElement]::ControlTypeProperty,
113
+ $ctMap[$ControlType]
114
+ )
115
+ }
116
+ }
117
+
118
+ # NOTE: Name matching is done AFTER FindAll via fuzzy match (case-insensitive
119
+ # contains). We do NOT add a PropertyCondition for Name — that would be exact-only
120
+ # and miss elements like "To recipients" when searching for "To".
121
+ # This matches the behavior of ps-bridge.ps1's Cmd-FindElement.
122
+
123
+ # Combine conditions
124
+ if ($conditions.Count -eq 0) {
125
+ $searchCondition = [System.Windows.Automation.Condition]::TrueCondition
126
+ } elseif ($conditions.Count -eq 1) {
127
+ $searchCondition = $conditions[0]
128
+ } else {
129
+ $searchCondition = New-Object System.Windows.Automation.AndCondition(
130
+ [System.Windows.Automation.Condition[]]$conditions
131
+ )
132
+ }
133
+
134
+ # Search descendants
135
+ $scope = [System.Windows.Automation.TreeScope]::Descendants
136
+ if ($ProcessId -eq 0) {
137
+ # If no process specified, only search children to avoid walking the entire desktop tree
138
+ $scope = [System.Windows.Automation.TreeScope]::Subtree
139
+ }
140
+
141
+ $elements = $searchRoot.FindAll($scope, $searchCondition)
142
+
143
+ $results = @()
144
+ $count = 0
145
+ $nameLower = if ($Name -ne "") { $Name.ToLower() } else { "" }
146
+
147
+ foreach ($el in $elements) {
148
+ if ($count -ge $MaxResults) { break }
149
+ try {
150
+ $c = $el.Current
151
+
152
+ # Fuzzy name matching (case-insensitive contains, strip keyboard shortcut suffix)
153
+ # e.g. searching "To" matches "To", "To recipients", "To:"
154
+ # e.g. searching "Save" matches "Save", "Save As...", "Save Ctrl+S"
155
+ if ($nameLower -ne "") {
156
+ $elName = ($c.Name -replace '\t.*$', '').Trim().ToLower()
157
+ if ($elName.Length -eq 0) { continue }
158
+ if (-not $elName.Contains($nameLower) -and -not $nameLower.Contains($elName)) { continue }
159
+ }
160
+
161
+ $rect = $c.BoundingRectangle
162
+ if ([double]::IsInfinity($rect.X) -or [double]::IsInfinity($rect.Y)) {
163
+ $bounds = @{ x = 0; y = 0; width = 0; height = 0 }
164
+ } else {
165
+ $bounds = @{
166
+ x = [int]$rect.X
167
+ y = [int]$rect.Y
168
+ width = [int]$rect.Width
169
+ height = [int]$rect.Height
170
+ }
171
+ }
172
+ $results += [ordered]@{
173
+ name = if ($c.Name) { $c.Name } else { "" }
174
+ automationId = if ($c.AutomationId) { $c.AutomationId } else { "" }
175
+ controlType = $c.ControlType.ProgrammaticName
176
+ className = if ($c.ClassName) { $c.ClassName } else { "" }
177
+ processId = $c.ProcessId
178
+ isEnabled = $c.IsEnabled
179
+ bounds = $bounds
180
+ }
181
+ $count++
182
+ } catch {
183
+ # Skip elements that throw on property access
184
+ }
185
+ }
186
+
187
+ # Always output a JSON array (PowerShell ConvertTo-Json returns object for single item, empty for none)
188
+ if ($results.Count -eq 0) {
189
+ [Console]::Out.Write("[]")
190
+ } elseif ($results.Count -eq 1) {
191
+ [Console]::Out.Write(("[" + ($results[0] | ConvertTo-Json -Depth 10 -Compress) + "]"))
192
+ } else {
193
+ [Console]::Out.Write(($results | ConvertTo-Json -Depth 10 -Compress))
194
+ }
195
+ } catch {
196
+ [Console]::Out.Write((@{ error = $_.Exception.Message } | ConvertTo-Json -Compress))
197
+ exit 1
198
+ }
@@ -0,0 +1,71 @@
1
+ <#
2
+ .SYNOPSIS
3
+ Gets the currently focused/foreground window.
4
+ .DESCRIPTION
5
+ Returns JSON with info about the foreground window using Win32 GetForegroundWindow.
6
+ #>
7
+
8
+ try {
9
+ Add-Type -AssemblyName UIAutomationClient
10
+ Add-Type -AssemblyName UIAutomationTypes
11
+
12
+ # Add Win32 API for GetForegroundWindow
13
+ Add-Type @"
14
+ using System;
15
+ using System.Runtime.InteropServices;
16
+ public class Win32 {
17
+ [DllImport("user32.dll")]
18
+ public static extern IntPtr GetForegroundWindow();
19
+ [DllImport("user32.dll", SetLastError = true)]
20
+ public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
21
+ }
22
+ "@
23
+ } catch {
24
+ [Console]::Out.Write((@{ error = "Failed to load assemblies: $($_.Exception.Message)" } | ConvertTo-Json -Compress))
25
+ exit 1
26
+ }
27
+
28
+ $ErrorActionPreference = 'Stop'
29
+
30
+ try {
31
+ # Get foreground window handle
32
+ $fgWindow = [Win32]::GetForegroundWindow()
33
+
34
+ if ($fgWindow -eq [IntPtr]::Zero) {
35
+ [Console]::Out.Write((@{ error = "No foreground window found" } | ConvertTo-Json -Compress))
36
+ exit 1
37
+ }
38
+
39
+ # Get process ID
40
+ $processId = 0
41
+ [void][Win32]::GetWindowThreadProcessId($fgWindow, [ref]$processId)
42
+
43
+ # Get process name
44
+ $processName = "unknown"
45
+ try {
46
+ $proc = [System.Diagnostics.Process]::GetProcessById($processId)
47
+ $processName = $proc.ProcessName
48
+ } catch { }
49
+
50
+ # Get window title via UI Automation
51
+ $title = ""
52
+ try {
53
+ $element = [System.Windows.Automation.AutomationElement]::FromHandle($fgWindow)
54
+ if ($element) {
55
+ $title = $element.Current.Name
56
+ }
57
+ } catch { }
58
+
59
+ $result = [ordered]@{
60
+ handle = [int]$fgWindow
61
+ processId = $processId
62
+ processName = $processName
63
+ title = $title
64
+ success = $true
65
+ }
66
+
67
+ [Console]::Out.Write(($result | ConvertTo-Json -Compress))
68
+ } catch {
69
+ [Console]::Out.Write((@{ error = $_.Exception.Message } | ConvertTo-Json -Compress))
70
+ exit 1
71
+ }
@@ -0,0 +1,183 @@
1
+ <#
2
+ .SYNOPSIS
3
+ Combined script: gets windows list + focused window UI tree in ONE call.
4
+ Eliminates multiple PowerShell spawn overhead.
5
+ .PARAMETER FocusedProcessId
6
+ If specified, includes the UI tree for this process's window.
7
+ .PARAMETER MaxDepth
8
+ Maximum UI tree depth (default 2).
9
+ #>
10
+ param(
11
+ [int]$FocusedProcessId = 0,
12
+ [int]$MaxDepth = 4
13
+ )
14
+
15
+ try {
16
+ Add-Type -AssemblyName UIAutomationClient
17
+ Add-Type -AssemblyName UIAutomationTypes
18
+ } catch {
19
+ [Console]::Out.Write((@{ error = "Failed to load UI Automation assemblies: $($_.Exception.Message)" } | ConvertTo-Json -Compress))
20
+ exit 1
21
+ }
22
+
23
+ $ErrorActionPreference = 'Stop'
24
+
25
+ # Interactive control types worth including
26
+ $interactiveTypes = @(
27
+ 'ControlType.Button', 'ControlType.Edit', 'ControlType.ComboBox',
28
+ 'ControlType.CheckBox', 'ControlType.RadioButton', 'ControlType.Hyperlink',
29
+ 'ControlType.MenuItem', 'ControlType.Menu', 'ControlType.Tab',
30
+ 'ControlType.TabItem', 'ControlType.ListItem', 'ControlType.TreeItem',
31
+ 'ControlType.Slider', 'ControlType.Document'
32
+ )
33
+
34
+ function ConvertTo-UINode {
35
+ param(
36
+ [System.Windows.Automation.AutomationElement]$Element,
37
+ [int]$Depth = 0,
38
+ [int]$TreeMaxDepth = 4
39
+ )
40
+
41
+ if ($null -eq $Element) { return $null }
42
+
43
+ try { $cur = $Element.Current } catch { return $null }
44
+
45
+ $typeName = $cur.ControlType.ProgrammaticName
46
+ $hasName = $cur.Name -and $cur.Name.Trim().Length -gt 0
47
+ $isInteractive = $interactiveTypes -contains $typeName
48
+
49
+ # Skip non-interactive unnamed elements
50
+ if (-not $isInteractive -and -not $hasName -and $Depth -gt 0) {
51
+ if ($Depth -ge $TreeMaxDepth) { return $null }
52
+ $childNodes = @()
53
+ try {
54
+ $kids = $Element.FindAll(
55
+ [System.Windows.Automation.TreeScope]::Children,
56
+ [System.Windows.Automation.Condition]::TrueCondition
57
+ )
58
+ foreach ($kid in $kids) {
59
+ $childNode = ConvertTo-UINode -Element $kid -Depth ($Depth + 1) -TreeMaxDepth $TreeMaxDepth
60
+ if ($null -ne $childNode) { $childNodes += $childNode }
61
+ }
62
+ } catch {}
63
+ if ($childNodes.Count -eq 0) { return $null }
64
+ return $childNodes
65
+ }
66
+
67
+ $rect = $cur.BoundingRectangle
68
+ if ([double]::IsInfinity($rect.X) -or [double]::IsInfinity($rect.Y)) {
69
+ $bounds = @{ x = 0; y = 0; width = 0; height = 0 }
70
+ } else {
71
+ $bounds = @{
72
+ x = [int]$rect.X
73
+ y = [int]$rect.Y
74
+ width = [int]$rect.Width
75
+ height = [int]$rect.Height
76
+ }
77
+ }
78
+
79
+ $node = [ordered]@{
80
+ name = if ($cur.Name) { $cur.Name } else { "" }
81
+ automationId = if ($cur.AutomationId) { $cur.AutomationId } else { "" }
82
+ controlType = $typeName
83
+ bounds = $bounds
84
+ children = @()
85
+ }
86
+
87
+ if ($Depth -lt $TreeMaxDepth) {
88
+ try {
89
+ $kids = $Element.FindAll(
90
+ [System.Windows.Automation.TreeScope]::Children,
91
+ [System.Windows.Automation.Condition]::TrueCondition
92
+ )
93
+ foreach ($kid in $kids) {
94
+ $childNode = ConvertTo-UINode -Element $kid -Depth ($Depth + 1) -TreeMaxDepth $TreeMaxDepth
95
+ if ($null -ne $childNode) {
96
+ if ($childNode -is [array]) { $node.children += $childNode }
97
+ else { $node.children += $childNode }
98
+ }
99
+ }
100
+ } catch {}
101
+ }
102
+
103
+ return $node
104
+ }
105
+
106
+ try {
107
+ $root = [System.Windows.Automation.AutomationElement]::RootElement
108
+
109
+ # 1. Get all windows
110
+ $windowCondition = New-Object System.Windows.Automation.PropertyCondition(
111
+ [System.Windows.Automation.AutomationElement]::ControlTypeProperty,
112
+ [System.Windows.Automation.ControlType]::Window
113
+ )
114
+ $allWindows = $root.FindAll(
115
+ [System.Windows.Automation.TreeScope]::Children,
116
+ $windowCondition
117
+ )
118
+
119
+ $windowList = @()
120
+ foreach ($win in $allWindows) {
121
+ try {
122
+ $c = $win.Current
123
+ if (-not $c.Name -or $c.Name.Trim().Length -eq 0) { continue }
124
+
125
+ $processName = ""
126
+ try {
127
+ $proc = [System.Diagnostics.Process]::GetProcessById($c.ProcessId)
128
+ $processName = $proc.ProcessName
129
+ } catch { $processName = "unknown" }
130
+
131
+ $rect = $c.BoundingRectangle
132
+ if ([double]::IsInfinity($rect.X)) {
133
+ $bounds = @{ x = 0; y = 0; width = 0; height = 0 }
134
+ } else {
135
+ $bounds = @{ x = [int]$rect.X; y = [int]$rect.Y; width = [int]$rect.Width; height = [int]$rect.Height }
136
+ }
137
+
138
+ $isMinimized = $false
139
+ try {
140
+ $winPattern = $win.GetCurrentPattern([System.Windows.Automation.WindowPattern]::Pattern)
141
+ if ($winPattern.Current.WindowVisualState -eq [System.Windows.Automation.WindowVisualState]::Minimized) {
142
+ $isMinimized = $true
143
+ }
144
+ } catch {}
145
+
146
+ $windowList += [ordered]@{
147
+ handle = $c.NativeWindowHandle
148
+ title = $c.Name
149
+ processName = $processName
150
+ processId = $c.ProcessId
151
+ bounds = $bounds
152
+ isMinimized = $isMinimized
153
+ }
154
+ } catch {}
155
+ }
156
+
157
+ # 2. Get focused window UI tree if requested
158
+ $uiTree = $null
159
+ if ($FocusedProcessId -gt 0) {
160
+ $condition = New-Object System.Windows.Automation.PropertyCondition(
161
+ [System.Windows.Automation.AutomationElement]::ProcessIdProperty,
162
+ $FocusedProcessId
163
+ )
164
+ $targetWindow = $root.FindFirst(
165
+ [System.Windows.Automation.TreeScope]::Children,
166
+ $condition
167
+ )
168
+ if ($null -ne $targetWindow) {
169
+ $uiTree = ConvertTo-UINode -Element $targetWindow -Depth 0 -TreeMaxDepth $MaxDepth
170
+ }
171
+ }
172
+
173
+ # 3. Return combined result
174
+ $result = [ordered]@{
175
+ windows = $windowList
176
+ uiTree = $uiTree
177
+ }
178
+
179
+ [Console]::Out.Write(($result | ConvertTo-Json -Depth 50 -Compress))
180
+ } catch {
181
+ [Console]::Out.Write((@{ error = $_.Exception.Message } | ConvertTo-Json -Compress))
182
+ exit 1
183
+ }
@@ -0,0 +1,66 @@
1
+ <#
2
+ .SYNOPSIS
3
+ Shim — returns window list. Use get-screen-context.ps1 for combined data.
4
+ #>
5
+ try {
6
+ Add-Type -AssemblyName UIAutomationClient
7
+ Add-Type -AssemblyName UIAutomationTypes
8
+ } catch {
9
+ [Console]::Out.Write((@() | ConvertTo-Json -Compress))
10
+ exit 0
11
+ }
12
+
13
+ $ErrorActionPreference = 'Stop'
14
+
15
+ try {
16
+ $root = [System.Windows.Automation.AutomationElement]::RootElement
17
+ $windowCondition = New-Object System.Windows.Automation.PropertyCondition(
18
+ [System.Windows.Automation.AutomationElement]::ControlTypeProperty,
19
+ [System.Windows.Automation.ControlType]::Window
20
+ )
21
+ $allWindows = $root.FindAll(
22
+ [System.Windows.Automation.TreeScope]::Children,
23
+ $windowCondition
24
+ )
25
+
26
+ $windowList = @()
27
+ foreach ($win in $allWindows) {
28
+ try {
29
+ $c = $win.Current
30
+ if (-not $c.Name -or $c.Name.Trim().Length -eq 0) { continue }
31
+ $processName = ""
32
+ try {
33
+ $proc = [System.Diagnostics.Process]::GetProcessById($c.ProcessId)
34
+ $processName = $proc.ProcessName
35
+ } catch { $processName = "unknown" }
36
+
37
+ $rect = $c.BoundingRectangle
38
+ if ([double]::IsInfinity($rect.X)) {
39
+ $bounds = @{ x = 0; y = 0; width = 0; height = 0 }
40
+ } else {
41
+ $bounds = @{ x = [int]$rect.X; y = [int]$rect.Y; width = [int]$rect.Width; height = [int]$rect.Height }
42
+ }
43
+
44
+ $isMinimized = $false
45
+ try {
46
+ $winPattern = $win.GetCurrentPattern([System.Windows.Automation.WindowPattern]::Pattern)
47
+ if ($winPattern.Current.WindowVisualState -eq [System.Windows.Automation.WindowVisualState]::Minimized) {
48
+ $isMinimized = $true
49
+ }
50
+ } catch {}
51
+
52
+ $windowList += [ordered]@{
53
+ handle = $c.NativeWindowHandle
54
+ title = $c.Name
55
+ processName = $processName
56
+ processId = $c.ProcessId
57
+ bounds = $bounds
58
+ isMinimized = $isMinimized
59
+ }
60
+ } catch {}
61
+ }
62
+
63
+ [Console]::Out.Write(($windowList | ConvertTo-Json -Depth 10 -Compress))
64
+ } catch {
65
+ [Console]::Out.Write((@() | ConvertTo-Json -Compress))
66
+ }
@@ -0,0 +1,46 @@
1
+ # install-panic-hotkey.ps1 — Windows panic stop for clawdcursor.
2
+ #
3
+ # Creates a global keyboard shortcut (default Ctrl+Alt+K) that FORCE-KILLS every
4
+ # running clawdcursor process — the daemon and its PowerShell UIA/OCR children —
5
+ # instantly, for when an autonomous run misbehaves. No dependencies (uses a
6
+ # Desktop shortcut's built-in HotKey; the .lnk must stay on the Desktop for the
7
+ # hotkey to stay registered).
8
+ #
9
+ # Usage:
10
+ # powershell -ExecutionPolicy Bypass -File install-panic-hotkey.ps1 # Ctrl+Alt+K
11
+ # powershell -ExecutionPolicy Bypass -File install-panic-hotkey.ps1 -HotKey "CTRL+ALT+Q"
12
+ param([string]$HotKey = 'CTRL+ALT+K')
13
+
14
+ $ErrorActionPreference = 'Stop'
15
+
16
+ # 1) Write the force-kill script to a stable, install-independent location.
17
+ $dir = Join-Path $env:USERPROFILE '.clawdcursor'
18
+ if (-not (Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null }
19
+ $kill = Join-Path $dir 'panic-kill.ps1'
20
+ $body = @'
21
+ # clawdcursor PANIC KILL — force-stop every clawdcursor process immediately.
22
+ $ErrorActionPreference = 'SilentlyContinue'
23
+ Get-CimInstance Win32_Process -Filter "Name='node.exe'" |
24
+ Where-Object { $_.CommandLine -match 'clawdcursor' -or $_.CommandLine -match 'cli\.js.*agent' } |
25
+ ForEach-Object { Stop-Process -Id $_.ProcessId -Force }
26
+ Get-CimInstance Win32_Process -Filter "Name='powershell.exe'" |
27
+ Where-Object { $_.CommandLine -match 'ps-bridge\.ps1' -or $_.CommandLine -match 'ocr-recognize\.ps1' } |
28
+ ForEach-Object { Stop-Process -Id $_.ProcessId -Force }
29
+ '@
30
+ Set-Content -Path $kill -Value $body -Encoding UTF8
31
+
32
+ # 2) Desktop shortcut whose HotKey Windows registers globally.
33
+ $ws = New-Object -ComObject WScript.Shell
34
+ $lnkPath = Join-Path ([Environment]::GetFolderPath('Desktop')) 'Stop ClawdCursor.lnk'
35
+ $lnk = $ws.CreateShortcut($lnkPath)
36
+ $lnk.TargetPath = 'powershell.exe'
37
+ $lnk.Arguments = "-NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File `"$kill`""
38
+ $lnk.HotKey = $HotKey
39
+ $lnk.IconLocation = 'powershell.exe,0'
40
+ $lnk.Description = 'Force-kill all clawdcursor processes (panic stop)'
41
+ $lnk.WindowStyle = 7
42
+ $lnk.Save()
43
+
44
+ Write-Host "[OK] Panic hotkey installed: $HotKey -> $lnkPath"
45
+ Write-Host " Press $HotKey anytime to force-kill clawdcursor."
46
+ Write-Host " (Keep 'Stop ClawdCursor.lnk' on the Desktop for the hotkey to stay active.)"