screenhand 0.2.0 → 0.3.1

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 (212) hide show
  1. package/README.md +165 -446
  2. package/bin/darwin-arm64/macos-bridge +0 -0
  3. package/dist/mcp-desktop.js +3615 -400
  4. package/dist/scripts/export-help-center.js +112 -0
  5. package/dist/scripts/marketing-loop.js +117 -0
  6. package/dist/scripts/observer-daemon.js +288 -0
  7. package/dist/scripts/orchestrator-daemon.js +399 -0
  8. package/dist/scripts/threads-campaign.js +208 -0
  9. package/dist/src/community/fetcher.js +109 -0
  10. package/dist/src/community/index.js +6 -0
  11. package/dist/src/community/publisher.js +191 -0
  12. package/dist/src/community/remote-api.js +121 -0
  13. package/dist/src/community/types.js +3 -0
  14. package/dist/src/community/validator.js +95 -0
  15. package/dist/src/context-tracker.js +489 -0
  16. package/dist/src/ingestion/coverage-auditor.js +233 -0
  17. package/dist/src/ingestion/doc-parser.js +164 -0
  18. package/dist/src/ingestion/index.js +8 -0
  19. package/dist/src/ingestion/menu-scanner.js +152 -0
  20. package/dist/src/ingestion/reference-merger.js +186 -0
  21. package/dist/src/ingestion/shortcut-extractor.js +180 -0
  22. package/dist/src/ingestion/tutorial-extractor.js +170 -0
  23. package/dist/src/ingestion/types.js +3 -0
  24. package/dist/src/jobs/manager.js +82 -14
  25. package/dist/src/jobs/runner.js +138 -15
  26. package/dist/src/learning/engine.js +356 -0
  27. package/dist/src/learning/index.js +9 -0
  28. package/dist/src/learning/locator-policy.js +120 -0
  29. package/dist/src/learning/pattern-policy.js +89 -0
  30. package/dist/src/learning/recovery-policy.js +116 -0
  31. package/dist/src/learning/sensor-policy.js +115 -0
  32. package/dist/src/learning/timing-model.js +204 -0
  33. package/dist/src/learning/topology-policy.js +90 -0
  34. package/dist/src/learning/types.js +9 -0
  35. package/dist/src/logging/timeline-logger.js +4 -1
  36. package/dist/src/memory/playbook-seeds.js +200 -0
  37. package/dist/src/memory/recall.js +60 -8
  38. package/dist/src/memory/service.js +30 -5
  39. package/dist/src/memory/store.js +34 -5
  40. package/dist/src/native/bridge-client.js +253 -31
  41. package/dist/src/observer/state.js +199 -0
  42. package/dist/src/observer/types.js +43 -0
  43. package/dist/src/orchestrator/state.js +68 -0
  44. package/dist/src/orchestrator/types.js +22 -0
  45. package/dist/src/perception/ax-source.js +162 -0
  46. package/dist/src/perception/cdp-source.js +162 -0
  47. package/dist/src/perception/coordinator.js +771 -0
  48. package/dist/src/perception/frame-differ.js +287 -0
  49. package/dist/src/perception/index.js +22 -0
  50. package/dist/src/perception/manager.js +199 -0
  51. package/dist/src/perception/types.js +47 -0
  52. package/dist/src/perception/vision-source.js +399 -0
  53. package/dist/src/planner/deterministic.js +298 -0
  54. package/dist/src/planner/executor.js +870 -0
  55. package/dist/src/planner/goal-store.js +92 -0
  56. package/dist/src/planner/index.js +21 -0
  57. package/dist/src/planner/planner.js +520 -0
  58. package/dist/src/planner/tool-registry.js +71 -0
  59. package/dist/src/planner/types.js +22 -0
  60. package/dist/src/platform/explorer.js +213 -0
  61. package/dist/src/platform/help-center-markdown.js +527 -0
  62. package/dist/src/platform/learner.js +257 -0
  63. package/dist/src/playbook/engine.js +296 -11
  64. package/dist/src/playbook/mcp-recorder.js +204 -0
  65. package/dist/src/playbook/recorder.js +3 -2
  66. package/dist/src/playbook/runner.js +1 -1
  67. package/dist/src/playbook/store.js +139 -10
  68. package/dist/src/recovery/detectors.js +156 -0
  69. package/dist/src/recovery/engine.js +327 -0
  70. package/dist/src/recovery/index.js +20 -0
  71. package/dist/src/recovery/strategies.js +274 -0
  72. package/dist/src/recovery/types.js +20 -0
  73. package/dist/src/runtime/accessibility-adapter.js +55 -18
  74. package/dist/src/runtime/applescript-adapter.js +8 -2
  75. package/dist/src/runtime/cdp-chrome-adapter.js +1 -1
  76. package/dist/src/runtime/executor.js +23 -3
  77. package/dist/src/runtime/locator-cache.js +24 -2
  78. package/dist/src/runtime/service.js +59 -15
  79. package/dist/src/runtime/session-manager.js +4 -1
  80. package/dist/src/runtime/vision-adapter.js +2 -1
  81. package/dist/src/state/app-map-types.js +72 -0
  82. package/dist/src/state/app-map.js +1974 -0
  83. package/dist/src/state/entity-tracker.js +108 -0
  84. package/dist/src/state/fusion.js +96 -0
  85. package/dist/src/state/index.js +21 -0
  86. package/dist/src/state/ladder-generator.js +236 -0
  87. package/dist/src/state/persistence.js +156 -0
  88. package/dist/src/state/types.js +17 -0
  89. package/dist/src/state/world-model.js +1456 -0
  90. package/dist/src/util/atomic-write.js +19 -4
  91. package/dist/src/util/sanitize.js +146 -0
  92. package/dist-app-maps/com.figma.Desktop.json +959 -0
  93. package/dist-app-maps/com.hnc.Discord.json +1146 -0
  94. package/dist-app-maps/notion.id.json +2831 -0
  95. package/dist-playbooks/canva-screenhand-carousel.json +445 -0
  96. package/dist-playbooks/codex-desktop.json +76 -0
  97. package/dist-playbooks/competitor-research-stack.json +122 -0
  98. package/dist-playbooks/davinci-color-grade.json +153 -0
  99. package/dist-playbooks/davinci-edit-timeline.json +162 -0
  100. package/dist-playbooks/davinci-render.json +114 -0
  101. package/dist-playbooks/devto.json +52 -0
  102. package/dist-playbooks/discord.json +41 -0
  103. package/dist-playbooks/google-flow-create-project.json +59 -0
  104. package/dist-playbooks/google-flow-edit-image.json +90 -0
  105. package/dist-playbooks/google-flow-edit-video.json +90 -0
  106. package/dist-playbooks/google-flow-generate-image.json +68 -0
  107. package/dist-playbooks/google-flow-generate-video.json +191 -0
  108. package/dist-playbooks/google-flow-open-project.json +48 -0
  109. package/dist-playbooks/google-flow-open-scenebuilder.json +64 -0
  110. package/dist-playbooks/google-flow-search-assets.json +64 -0
  111. package/dist-playbooks/instagram.json +57 -0
  112. package/dist-playbooks/linkedin.json +52 -0
  113. package/dist-playbooks/n8n.json +43 -0
  114. package/dist-playbooks/reddit.json +52 -0
  115. package/dist-playbooks/threads.json +59 -0
  116. package/dist-playbooks/x-twitter.json +59 -0
  117. package/dist-playbooks/youtube.json +59 -0
  118. package/dist-references/canva.json +646 -0
  119. package/dist-references/codex-desktop.json +305 -0
  120. package/dist-references/davinci-resolve-keyboard.json +594 -0
  121. package/dist-references/davinci-resolve-menu-map.json +1139 -0
  122. package/dist-references/davinci-resolve-menus-batch1.json +116 -0
  123. package/dist-references/davinci-resolve-menus-batch2.json +372 -0
  124. package/dist-references/davinci-resolve-menus-batch3.json +330 -0
  125. package/dist-references/davinci-resolve-menus-batch4.json +297 -0
  126. package/dist-references/davinci-resolve-shortcuts.json +333 -0
  127. package/dist-references/devpost.json +186 -0
  128. package/dist-references/devto.json +317 -0
  129. package/dist-references/discord.json +549 -0
  130. package/dist-references/figma.json +1186 -0
  131. package/dist-references/finder.json +146 -0
  132. package/dist-references/google-ads-transparency.json +95 -0
  133. package/dist-references/google-flow.json +649 -0
  134. package/dist-references/instagram.json +341 -0
  135. package/dist-references/linkedin.json +324 -0
  136. package/dist-references/meta-ad-library.json +86 -0
  137. package/dist-references/n8n.json +387 -0
  138. package/dist-references/notes.json +27 -0
  139. package/dist-references/notion.json +163 -0
  140. package/dist-references/reddit.json +341 -0
  141. package/dist-references/threads.json +337 -0
  142. package/dist-references/x-twitter.json +403 -0
  143. package/dist-references/youtube.json +373 -0
  144. package/native/macos-bridge/Package.swift +22 -0
  145. package/native/macos-bridge/Sources/AccessibilityBridge.swift +482 -0
  146. package/native/macos-bridge/Sources/AppManagement.swift +339 -0
  147. package/native/macos-bridge/Sources/CoreGraphicsBridge.swift +537 -0
  148. package/native/macos-bridge/Sources/ObserverBridge.swift +120 -0
  149. package/native/macos-bridge/Sources/StreamCapture.swift +136 -0
  150. package/native/macos-bridge/Sources/VisionBridge.swift +238 -0
  151. package/native/macos-bridge/Sources/main.swift +498 -0
  152. package/native/windows-bridge/AppManagement.cs +234 -0
  153. package/native/windows-bridge/InputBridge.cs +436 -0
  154. package/native/windows-bridge/Program.cs +270 -0
  155. package/native/windows-bridge/ScreenCapture.cs +453 -0
  156. package/native/windows-bridge/UIAutomationBridge.cs +571 -0
  157. package/native/windows-bridge/WindowsBridge.csproj +17 -0
  158. package/package.json +12 -1
  159. package/scripts/postinstall.cjs +127 -0
  160. package/dist/.audit-log.jsonl +0 -55
  161. package/dist/.screenhand/memory/.lock +0 -1
  162. package/dist/.screenhand/memory/actions.jsonl +0 -85
  163. package/dist/.screenhand/memory/errors.jsonl +0 -5
  164. package/dist/.screenhand/memory/errors.jsonl.bak +0 -4
  165. package/dist/.screenhand/memory/state.json +0 -35
  166. package/dist/.screenhand/memory/state.json.bak +0 -35
  167. package/dist/.screenhand/memory/strategies.jsonl +0 -12
  168. package/dist/agent/cli.js +0 -73
  169. package/dist/agent/loop.js +0 -258
  170. package/dist/config.js +0 -9
  171. package/dist/index.js +0 -56
  172. package/dist/logging/timeline-logger.js +0 -29
  173. package/dist/mcp/mcp-stdio-server.js +0 -448
  174. package/dist/mcp/server.js +0 -347
  175. package/dist/mcp-entry.js +0 -59
  176. package/dist/memory/recall.js +0 -160
  177. package/dist/memory/research.js +0 -98
  178. package/dist/memory/seeds.js +0 -89
  179. package/dist/memory/session.js +0 -161
  180. package/dist/memory/store.js +0 -391
  181. package/dist/memory/types.js +0 -4
  182. package/dist/monitor/codex-monitor.js +0 -377
  183. package/dist/monitor/task-queue.js +0 -84
  184. package/dist/monitor/types.js +0 -49
  185. package/dist/native/bridge-client.js +0 -174
  186. package/dist/native/macos-bridge-client.js +0 -5
  187. package/dist/npm-publish-helper.js +0 -117
  188. package/dist/npm-token-cdp.js +0 -113
  189. package/dist/npm-token-create.js +0 -135
  190. package/dist/npm-token-finish.js +0 -126
  191. package/dist/playbook/engine.js +0 -193
  192. package/dist/playbook/index.js +0 -4
  193. package/dist/playbook/recorder.js +0 -519
  194. package/dist/playbook/runner.js +0 -392
  195. package/dist/playbook/store.js +0 -166
  196. package/dist/playbook/types.js +0 -4
  197. package/dist/runtime/accessibility-adapter.js +0 -377
  198. package/dist/runtime/app-adapter.js +0 -48
  199. package/dist/runtime/applescript-adapter.js +0 -283
  200. package/dist/runtime/ax-role-map.js +0 -80
  201. package/dist/runtime/browser-adapter.js +0 -36
  202. package/dist/runtime/cdp-chrome-adapter.js +0 -505
  203. package/dist/runtime/composite-adapter.js +0 -205
  204. package/dist/runtime/executor.js +0 -250
  205. package/dist/runtime/locator-cache.js +0 -12
  206. package/dist/runtime/planning-loop.js +0 -47
  207. package/dist/runtime/service.js +0 -372
  208. package/dist/runtime/session-manager.js +0 -28
  209. package/dist/runtime/state-observer.js +0 -105
  210. package/dist/runtime/vision-adapter.js +0 -208
  211. package/dist/test-mcp-protocol.js +0 -138
  212. package/dist/types.js +0 -1
@@ -0,0 +1,270 @@
1
+ using System.Text.Json;
2
+ using System.Text.Json.Nodes;
3
+
4
+ namespace WindowsBridge;
5
+
6
+ /// <summary>
7
+ /// JSON-RPC over stdio bridge for Windows native APIs.
8
+ /// Reads JSON requests from stdin (one per line), dispatches to the appropriate bridge,
9
+ /// and writes JSON responses to stdout (one per line).
10
+ /// Mirrors the protocol of the macOS Swift bridge exactly.
11
+ /// </summary>
12
+ class Program
13
+ {
14
+ private static readonly AppManagement _appManagement = new();
15
+ private static readonly UIAutomationBridge _uiAutomation = new();
16
+ private static readonly InputBridge _input = new();
17
+ private static readonly ScreenCapture _screenCapture = new();
18
+
19
+ private static readonly object _outputLock = new();
20
+ private static readonly JsonSerializerOptions _jsonOptions = new()
21
+ {
22
+ PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
23
+ WriteIndented = false,
24
+ };
25
+
26
+ static void Main(string[] args)
27
+ {
28
+ Console.InputEncoding = System.Text.Encoding.UTF8;
29
+ Console.OutputEncoding = System.Text.Encoding.UTF8;
30
+
31
+ string? line;
32
+ while ((line = Console.ReadLine()) != null)
33
+ {
34
+ if (string.IsNullOrWhiteSpace(line)) continue;
35
+
36
+ try
37
+ {
38
+ var request = JsonSerializer.Deserialize<JsonRpcRequest>(line, _jsonOptions);
39
+ if (request == null)
40
+ {
41
+ WriteError(0, -32700, "Parse error: null request");
42
+ continue;
43
+ }
44
+
45
+ try
46
+ {
47
+ var result = Dispatch(request.Method, request.Params);
48
+ WriteResult(request.Id, result);
49
+ }
50
+ catch (BridgeException ex)
51
+ {
52
+ WriteError(request.Id, -1, ex.Message);
53
+ }
54
+ catch (Exception ex)
55
+ {
56
+ WriteError(request.Id, -1, ex.Message);
57
+ }
58
+ }
59
+ catch (Exception ex)
60
+ {
61
+ WriteError(0, -32700, $"Parse error: {ex.Message}");
62
+ }
63
+ }
64
+ }
65
+
66
+ private static object Dispatch(string method, JsonObject? p)
67
+ {
68
+ return method switch
69
+ {
70
+ // Lifecycle
71
+ "ping" => new Dictionary<string, object>
72
+ {
73
+ ["pong"] = true,
74
+ ["pid"] = Environment.ProcessId,
75
+ ["accessible"] = true, // UI Automation doesn't need special permissions on Windows
76
+ },
77
+ "check_permissions" => new Dictionary<string, object>
78
+ {
79
+ ["trusted"] = true, // No special permissions needed on Windows for UIA
80
+ },
81
+
82
+ // App Management
83
+ "app.launch" => _appManagement.LaunchApp(RequiredParam<string>(p, "bundleId")),
84
+ "app.focus" => _appManagement.FocusApp(RequiredParam<string>(p, "bundleId")),
85
+ "app.list" => _appManagement.ListRunningApps(),
86
+ "app.windows" => _appManagement.ListWindows(),
87
+ "app.frontmost" => _appManagement.FrontmostApp(),
88
+
89
+ // UI Automation (Accessibility equivalent)
90
+ "ax.findElement" => _uiAutomation.FindElement(
91
+ RequiredParam<int>(p, "pid"),
92
+ Param<string>(p, "role"),
93
+ Param<string>(p, "title"),
94
+ Param<string>(p, "value"),
95
+ Param<string>(p, "identifier"),
96
+ Param<bool>(p, "exact") ?? true),
97
+ "ax.getElementTree" => _uiAutomation.GetElementTree(
98
+ RequiredParam<int>(p, "pid"),
99
+ Param<int>(p, "maxDepth") ?? 5),
100
+ "ax.performAction" => _uiAutomation.PerformAction(
101
+ RequiredParam<int>(p, "pid"),
102
+ RequiredParam<int[]>(p, "elementPath"),
103
+ Param<string>(p, "action") ?? "AXPress"),
104
+ "ax.setElementValue" => _uiAutomation.SetElementValue(
105
+ RequiredParam<int>(p, "pid"),
106
+ RequiredParam<int[]>(p, "elementPath"),
107
+ RequiredParam<string>(p, "value")),
108
+ "ax.getElementValue" => _uiAutomation.GetElementValue(
109
+ RequiredParam<int>(p, "pid"),
110
+ RequiredParam<int[]>(p, "elementPath")),
111
+ "ax.menuClick" => _uiAutomation.MenuClick(
112
+ RequiredParam<int>(p, "pid"),
113
+ RequiredParam<string[]>(p, "menuPath")),
114
+
115
+ // Observer (stub — Windows UIA events could be added later)
116
+ "observer.start" => new Dictionary<string, object>
117
+ {
118
+ ["ok"] = true,
119
+ ["stub"] = true,
120
+ ["message"] = "UI Automation event observation not yet implemented on Windows",
121
+ },
122
+ "observer.stop" => new Dictionary<string, object>
123
+ {
124
+ ["ok"] = true,
125
+ ["stub"] = true,
126
+ ["message"] = "UI Automation event observation not yet implemented on Windows",
127
+ },
128
+
129
+ // Input (CoreGraphics equivalent)
130
+ "cg.mouseClick" => _input.MouseClick(
131
+ RequiredParam<double>(p, "x"),
132
+ RequiredParam<double>(p, "y"),
133
+ Param<string>(p, "button") ?? "left",
134
+ Param<int>(p, "clickCount") ?? 1),
135
+ "cg.mouseMove" => _input.MouseMove(
136
+ RequiredParam<double>(p, "x"),
137
+ RequiredParam<double>(p, "y")),
138
+ "cg.mouseDrag" => _input.MouseDrag(
139
+ RequiredParam<double>(p, "fromX"),
140
+ RequiredParam<double>(p, "fromY"),
141
+ RequiredParam<double>(p, "toX"),
142
+ RequiredParam<double>(p, "toY")),
143
+ "cg.mouseFlick" => _input.MouseDrag( // Map flick to fast drag on Windows
144
+ RequiredParam<double>(p, "fromX"),
145
+ RequiredParam<double>(p, "fromY"),
146
+ RequiredParam<double>(p, "toX"),
147
+ RequiredParam<double>(p, "toY")),
148
+ "cg.keyCombo" => _input.KeyCombo(RequiredParam<string[]>(p, "keys")),
149
+ "cg.typeText" => _input.TypeText(RequiredParam<string>(p, "text")),
150
+ "cg.scroll" => _input.Scroll(
151
+ RequiredParam<double>(p, "x"),
152
+ RequiredParam<double>(p, "y"),
153
+ Param<int>(p, "deltaX") ?? 0,
154
+ Param<int>(p, "deltaY") ?? 0),
155
+ "cg.captureScreen" => _screenCapture.CaptureScreen(
156
+ Param<Dictionary<string, double>>(p, "region")),
157
+ "cg.captureWindow" => _screenCapture.CaptureWindow(
158
+ RequiredParam<int>(p, "windowId")),
159
+ "cg.captureWindowBuffer" => _screenCapture.CaptureWindowBuffer(
160
+ RequiredParam<int>(p, "windowId")),
161
+
162
+ // Vision (OCR)
163
+ "vision.findText" => _screenCapture.FindText(
164
+ RequiredParam<string>(p, "imagePath"),
165
+ Param<string>(p, "searchText")),
166
+ "vision.ocr" => _screenCapture.Ocr(
167
+ RequiredParam<string>(p, "imagePath")),
168
+ "vision.ocrRegion" => _screenCapture.OcrRegion(
169
+ RequiredParam<int>(p, "windowId"),
170
+ RequiredParam<Dictionary<string, double>>(p, "region")),
171
+
172
+ _ => throw new BridgeException($"Unknown method: {method}"),
173
+ };
174
+ }
175
+
176
+ // Parameter helpers (mirror Swift's param/requiredParam)
177
+ private static T? Param<T>(JsonObject? p, string key)
178
+ {
179
+ if (p == null || !p.ContainsKey(key) || p[key] == null) return default;
180
+
181
+ var node = p[key]!;
182
+
183
+ // Handle numeric coercion
184
+ if (typeof(T) == typeof(double) && node is JsonValue jv)
185
+ {
186
+ if (jv.TryGetValue<double>(out var d)) return (T)(object)d;
187
+ if (jv.TryGetValue<int>(out var i)) return (T)(object)(double)i;
188
+ if (jv.TryGetValue<long>(out var l)) return (T)(object)(double)l;
189
+ }
190
+ if (typeof(T) == typeof(int) && node is JsonValue jv2)
191
+ {
192
+ if (jv2.TryGetValue<int>(out var i)) return (T)(object)i;
193
+ if (jv2.TryGetValue<double>(out var d)) return (T)(object)(int)d;
194
+ if (jv2.TryGetValue<long>(out var l)) return (T)(object)(int)l;
195
+ }
196
+
197
+ try
198
+ {
199
+ return node.Deserialize<T>(_jsonOptions);
200
+ }
201
+ catch
202
+ {
203
+ return default;
204
+ }
205
+ }
206
+
207
+ private static T RequiredParam<T>(JsonObject? p, string key)
208
+ {
209
+ var value = Param<T>(p, key);
210
+ if (value == null)
211
+ throw new BridgeException($"Missing required parameter: {key}");
212
+ return value;
213
+ }
214
+
215
+ // Output helpers
216
+ private static void WriteResult(int id, object result)
217
+ {
218
+ var response = new Dictionary<string, object?>
219
+ {
220
+ ["id"] = id,
221
+ ["result"] = result,
222
+ ["error"] = null,
223
+ };
224
+ WriteLine(response);
225
+ }
226
+
227
+ private static void WriteError(int id, int code, string message)
228
+ {
229
+ var response = new Dictionary<string, object?>
230
+ {
231
+ ["id"] = id,
232
+ ["result"] = null,
233
+ ["error"] = new Dictionary<string, object> { ["code"] = code, ["message"] = message },
234
+ };
235
+ WriteLine(response);
236
+ }
237
+
238
+ public static void WriteEvent(Dictionary<string, object> eventData)
239
+ {
240
+ var wrapped = new Dictionary<string, object>
241
+ {
242
+ ["id"] = 0,
243
+ ["event"] = eventData,
244
+ };
245
+ WriteLine(wrapped);
246
+ }
247
+
248
+ private static void WriteLine(object obj)
249
+ {
250
+ var json = JsonSerializer.Serialize(obj, _jsonOptions);
251
+ lock (_outputLock)
252
+ {
253
+ Console.WriteLine(json);
254
+ Console.Out.Flush();
255
+ }
256
+ }
257
+ }
258
+
259
+ // JSON-RPC types
260
+ class JsonRpcRequest
261
+ {
262
+ public int Id { get; set; }
263
+ public string Method { get; set; } = "";
264
+ public JsonObject? Params { get; set; }
265
+ }
266
+
267
+ class BridgeException : Exception
268
+ {
269
+ public BridgeException(string message) : base(message) { }
270
+ }