@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.
- package/CHANGELOG.md +2264 -0
- package/LICENSE +21 -0
- package/README.md +385 -0
- package/SECURITY.md +44 -0
- package/SKILL.md +503 -0
- package/dist/core/agent-loop/agent.d.ts +42 -0
- package/dist/core/agent-loop/agent.js +1023 -0
- package/dist/core/agent-loop/agent.js.map +1 -0
- package/dist/core/agent-loop/batch-tool.d.ts +25 -0
- package/dist/core/agent-loop/batch-tool.js +218 -0
- package/dist/core/agent-loop/batch-tool.js.map +1 -0
- package/dist/core/agent-loop/coord-scale.d.ts +72 -0
- package/dist/core/agent-loop/coord-scale.js +89 -0
- package/dist/core/agent-loop/coord-scale.js.map +1 -0
- package/dist/core/agent-loop/focus-guard.d.ts +24 -0
- package/dist/core/agent-loop/focus-guard.js +29 -0
- package/dist/core/agent-loop/focus-guard.js.map +1 -0
- package/dist/core/agent-loop/project-mcp.d.ts +97 -0
- package/dist/core/agent-loop/project-mcp.js +253 -0
- package/dist/core/agent-loop/project-mcp.js.map +1 -0
- package/dist/core/agent-loop/prompt.d.ts +45 -0
- package/dist/core/agent-loop/prompt.js +426 -0
- package/dist/core/agent-loop/prompt.js.map +1 -0
- package/dist/core/agent-loop/tool-meta.d.ts +93 -0
- package/dist/core/agent-loop/tool-meta.js +651 -0
- package/dist/core/agent-loop/tool-meta.js.map +1 -0
- package/dist/core/agent-loop/tools.d.ts +38 -0
- package/dist/core/agent-loop/tools.js +2134 -0
- package/dist/core/agent-loop/tools.js.map +1 -0
- package/dist/core/agent-loop/types.d.ts +170 -0
- package/dist/core/agent-loop/types.js +12 -0
- package/dist/core/agent-loop/types.js.map +1 -0
- package/dist/core/agent.d.ts +51 -0
- package/dist/core/agent.js +245 -0
- package/dist/core/agent.js.map +1 -0
- package/dist/core/app-categories.d.ts +67 -0
- package/dist/core/app-categories.js +108 -0
- package/dist/core/app-categories.js.map +1 -0
- package/dist/core/banner.d.ts +70 -0
- package/dist/core/banner.js +245 -0
- package/dist/core/banner.js.map +1 -0
- package/dist/core/classify/capability.d.ts +45 -0
- package/dist/core/classify/capability.js +78 -0
- package/dist/core/classify/capability.js.map +1 -0
- package/dist/core/decompose/llm-decomposer.d.ts +35 -0
- package/dist/core/decompose/llm-decomposer.js +156 -0
- package/dist/core/decompose/llm-decomposer.js.map +1 -0
- package/dist/core/decompose/parser.d.ts +27 -0
- package/dist/core/decompose/parser.js +101 -0
- package/dist/core/decompose/parser.js.map +1 -0
- package/dist/core/observability/correlation.d.ts +19 -0
- package/dist/core/observability/correlation.js +36 -0
- package/dist/core/observability/correlation.js.map +1 -0
- package/dist/core/observability/cost-meter.d.ts +51 -0
- package/dist/core/observability/cost-meter.js +134 -0
- package/dist/core/observability/cost-meter.js.map +1 -0
- package/dist/core/observability/logger.d.ts +61 -0
- package/dist/core/observability/logger.js +550 -0
- package/dist/core/observability/logger.js.map +1 -0
- package/dist/core/router/aliases.d.ts +50 -0
- package/dist/core/router/aliases.js +104 -0
- package/dist/core/router/aliases.js.map +1 -0
- package/dist/core/router/normalize.d.ts +41 -0
- package/dist/core/router/normalize.js +80 -0
- package/dist/core/router/normalize.js.map +1 -0
- package/dist/core/safety.d.ts +126 -0
- package/dist/core/safety.js +568 -0
- package/dist/core/safety.js.map +1 -0
- package/dist/core/sense/a11y-resolver.d.ts +73 -0
- package/dist/core/sense/a11y-resolver.js +76 -0
- package/dist/core/sense/a11y-resolver.js.map +1 -0
- package/dist/core/sense/fingerprint.d.ts +41 -0
- package/dist/core/sense/fingerprint.js +123 -0
- package/dist/core/sense/fingerprint.js.map +1 -0
- package/dist/core/sense/rank.d.ts +70 -0
- package/dist/core/sense/rank.js +192 -0
- package/dist/core/sense/rank.js.map +1 -0
- package/dist/core/sense/reactive-check.d.ts +40 -0
- package/dist/core/sense/reactive-check.js +48 -0
- package/dist/core/sense/reactive-check.js.map +1 -0
- package/dist/core/sense/snapshot.d.ts +19 -0
- package/dist/core/sense/snapshot.js +100 -0
- package/dist/core/sense/snapshot.js.map +1 -0
- package/dist/core/sense/types.d.ts +66 -0
- package/dist/core/sense/types.js +9 -0
- package/dist/core/sense/types.js.map +1 -0
- package/dist/core/sense/ui-map-anchors.d.ts +7 -0
- package/dist/core/sense/ui-map-anchors.js +24 -0
- package/dist/core/sense/ui-map-anchors.js.map +1 -0
- package/dist/core/sense/ui-map-elements.d.ts +5 -0
- package/dist/core/sense/ui-map-elements.js +33 -0
- package/dist/core/sense/ui-map-elements.js.map +1 -0
- package/dist/core/sense/ui-map-find.d.ts +56 -0
- package/dist/core/sense/ui-map-find.js +153 -0
- package/dist/core/sense/ui-map-find.js.map +1 -0
- package/dist/core/sense/ui-map-fuse.d.ts +4 -0
- package/dist/core/sense/ui-map-fuse.js +44 -0
- package/dist/core/sense/ui-map-fuse.js.map +1 -0
- package/dist/core/sense/ui-map-geom.d.ts +3 -0
- package/dist/core/sense/ui-map-geom.js +16 -0
- package/dist/core/sense/ui-map-geom.js.map +1 -0
- package/dist/core/sense/ui-map-holder.d.ts +58 -0
- package/dist/core/sense/ui-map-holder.js +87 -0
- package/dist/core/sense/ui-map-holder.js.map +1 -0
- package/dist/core/sense/ui-map-normalize.d.ts +19 -0
- package/dist/core/sense/ui-map-normalize.js +65 -0
- package/dist/core/sense/ui-map-normalize.js.map +1 -0
- package/dist/core/sense/ui-map-render.d.ts +4 -0
- package/dist/core/sense/ui-map-render.js +34 -0
- package/dist/core/sense/ui-map-render.js.map +1 -0
- package/dist/core/sense/ui-map-resolve.d.ts +41 -0
- package/dist/core/sense/ui-map-resolve.js +59 -0
- package/dist/core/sense/ui-map-resolve.js.map +1 -0
- package/dist/core/sense/ui-map-types.d.ts +66 -0
- package/dist/core/sense/ui-map-types.js +11 -0
- package/dist/core/sense/ui-map-types.js.map +1 -0
- package/dist/core/sense/ui-map.d.ts +29 -0
- package/dist/core/sense/ui-map.js +113 -0
- package/dist/core/sense/ui-map.js.map +1 -0
- package/dist/core/verify/assertions.d.ts +132 -0
- package/dist/core/verify/assertions.js +284 -0
- package/dist/core/verify/assertions.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/browser-config.d.ts +36 -0
- package/dist/llm/browser-config.js +83 -0
- package/dist/llm/browser-config.js.map +1 -0
- package/dist/llm/client.d.ts +268 -0
- package/dist/llm/client.js +1094 -0
- package/dist/llm/client.js.map +1 -0
- package/dist/llm/config.d.ts +79 -0
- package/dist/llm/config.js +375 -0
- package/dist/llm/config.js.map +1 -0
- package/dist/llm/credentials.d.ts +35 -0
- package/dist/llm/credentials.js +491 -0
- package/dist/llm/credentials.js.map +1 -0
- package/dist/llm/external-creds.d.ts +42 -0
- package/dist/llm/external-creds.js +169 -0
- package/dist/llm/external-creds.js.map +1 -0
- package/dist/llm/providers.d.ts +123 -0
- package/dist/llm/providers.js +717 -0
- package/dist/llm/providers.js.map +1 -0
- package/dist/paths.d.ts +31 -0
- package/dist/paths.js +147 -0
- package/dist/paths.js.map +1 -0
- package/dist/platform/accessibility.d.ts +139 -0
- package/dist/platform/accessibility.js +670 -0
- package/dist/platform/accessibility.js.map +1 -0
- package/dist/platform/cdp-driver.d.ts +318 -0
- package/dist/platform/cdp-driver.js +1179 -0
- package/dist/platform/cdp-driver.js.map +1 -0
- package/dist/platform/index.d.ts +11 -0
- package/dist/platform/index.js +69 -0
- package/dist/platform/index.js.map +1 -0
- package/dist/platform/keys.d.ts +17 -0
- package/dist/platform/keys.js +129 -0
- package/dist/platform/keys.js.map +1 -0
- package/dist/platform/launch-poll.d.ts +101 -0
- package/dist/platform/launch-poll.js +177 -0
- package/dist/platform/launch-poll.js.map +1 -0
- package/dist/platform/linux.d.ts +173 -0
- package/dist/platform/linux.js +1253 -0
- package/dist/platform/linux.js.map +1 -0
- package/dist/platform/macos.d.ts +136 -0
- package/dist/platform/macos.js +976 -0
- package/dist/platform/macos.js.map +1 -0
- package/dist/platform/native-desktop.d.ts +145 -0
- package/dist/platform/native-desktop.js +936 -0
- package/dist/platform/native-desktop.js.map +1 -0
- package/dist/platform/native-helper.d.ts +130 -0
- package/dist/platform/native-helper.js +592 -0
- package/dist/platform/native-helper.js.map +1 -0
- package/dist/platform/ocr-engine.d.ts +78 -0
- package/dist/platform/ocr-engine.js +363 -0
- package/dist/platform/ocr-engine.js.map +1 -0
- package/dist/platform/ps-runner.d.ts +28 -0
- package/dist/platform/ps-runner.js +228 -0
- package/dist/platform/ps-runner.js.map +1 -0
- package/dist/platform/types.d.ts +397 -0
- package/dist/platform/types.js +15 -0
- package/dist/platform/types.js.map +1 -0
- package/dist/platform/uri-handler.d.ts +75 -0
- package/dist/platform/uri-handler.js +273 -0
- package/dist/platform/uri-handler.js.map +1 -0
- package/dist/platform/wayland-backend.d.ts +53 -0
- package/dist/platform/wayland-backend.js +348 -0
- package/dist/platform/wayland-backend.js.map +1 -0
- package/dist/platform/windows.d.ts +232 -0
- package/dist/platform/windows.js +1210 -0
- package/dist/platform/windows.js.map +1 -0
- package/dist/postbuild.d.ts +10 -0
- package/dist/postbuild.js +98 -0
- package/dist/postbuild.js.map +1 -0
- package/dist/schema/snapshot.d.ts +33 -0
- package/dist/schema/snapshot.js +90 -0
- package/dist/schema/snapshot.js.map +1 -0
- package/dist/shortcuts.d.ts +30 -0
- package/dist/shortcuts.js +261 -0
- package/dist/shortcuts.js.map +1 -0
- package/dist/surface/cli.d.ts +7 -0
- package/dist/surface/cli.js +1556 -0
- package/dist/surface/cli.js.map +1 -0
- package/dist/surface/dashboard.d.ts +8 -0
- package/dist/surface/dashboard.js +1193 -0
- package/dist/surface/dashboard.js.map +1 -0
- package/dist/surface/doctor.d.ts +29 -0
- package/dist/surface/doctor.js +1514 -0
- package/dist/surface/doctor.js.map +1 -0
- package/dist/surface/format.d.ts +10 -0
- package/dist/surface/format.js +37 -0
- package/dist/surface/format.js.map +1 -0
- package/dist/surface/http-utility.d.ts +65 -0
- package/dist/surface/http-utility.js +336 -0
- package/dist/surface/http-utility.js.map +1 -0
- package/dist/surface/mcp-server.d.ts +91 -0
- package/dist/surface/mcp-server.js +280 -0
- package/dist/surface/mcp-server.js.map +1 -0
- package/dist/surface/onboarding.d.ts +15 -0
- package/dist/surface/onboarding.js +184 -0
- package/dist/surface/onboarding.js.map +1 -0
- package/dist/surface/pidfile.d.ts +79 -0
- package/dist/surface/pidfile.js +263 -0
- package/dist/surface/pidfile.js.map +1 -0
- package/dist/surface/readiness.d.ts +45 -0
- package/dist/surface/readiness.js +230 -0
- package/dist/surface/readiness.js.map +1 -0
- package/dist/surface/report.d.ts +68 -0
- package/dist/surface/report.js +341 -0
- package/dist/surface/report.js.map +1 -0
- package/dist/surface/skill-register.d.ts +14 -0
- package/dist/surface/skill-register.js +150 -0
- package/dist/surface/skill-register.js.map +1 -0
- package/dist/surface/version.d.ts +6 -0
- package/dist/surface/version.js +27 -0
- package/dist/surface/version.js.map +1 -0
- package/dist/tools/a11y.d.ts +8 -0
- package/dist/tools/a11y.js +545 -0
- package/dist/tools/a11y.js.map +1 -0
- package/dist/tools/a11y_depth.d.ts +19 -0
- package/dist/tools/a11y_depth.js +455 -0
- package/dist/tools/a11y_depth.js.map +1 -0
- package/dist/tools/agent.d.ts +15 -0
- package/dist/tools/agent.js +248 -0
- package/dist/tools/agent.js.map +1 -0
- package/dist/tools/batch.d.ts +46 -0
- package/dist/tools/batch.js +230 -0
- package/dist/tools/batch.js.map +1 -0
- package/dist/tools/cdp.d.ts +8 -0
- package/dist/tools/cdp.js +233 -0
- package/dist/tools/cdp.js.map +1 -0
- package/dist/tools/compact.d.ts +63 -0
- package/dist/tools/compact.js +418 -0
- package/dist/tools/compact.js.map +1 -0
- package/dist/tools/cost-class.d.ts +38 -0
- package/dist/tools/cost-class.js +117 -0
- package/dist/tools/cost-class.js.map +1 -0
- package/dist/tools/desktop.d.ts +9 -0
- package/dist/tools/desktop.js +346 -0
- package/dist/tools/desktop.js.map +1 -0
- package/dist/tools/electron_bridge.d.ts +41 -0
- package/dist/tools/electron_bridge.js +261 -0
- package/dist/tools/electron_bridge.js.map +1 -0
- package/dist/tools/extras.d.ts +22 -0
- package/dist/tools/extras.js +942 -0
- package/dist/tools/extras.js.map +1 -0
- package/dist/tools/favorites.d.ts +13 -0
- package/dist/tools/favorites.js +137 -0
- package/dist/tools/favorites.js.map +1 -0
- package/dist/tools/introspection.d.ts +13 -0
- package/dist/tools/introspection.js +55 -0
- package/dist/tools/introspection.js.map +1 -0
- package/dist/tools/ocr.d.ts +8 -0
- package/dist/tools/ocr.js +66 -0
- package/dist/tools/ocr.js.map +1 -0
- package/dist/tools/orchestration.d.ts +7 -0
- package/dist/tools/orchestration.js +377 -0
- package/dist/tools/orchestration.js.map +1 -0
- package/dist/tools/playbooks/extract-compose.d.ts +22 -0
- package/dist/tools/playbooks/extract-compose.js +85 -0
- package/dist/tools/playbooks/extract-compose.js.map +1 -0
- package/dist/tools/playbooks/find-replace.d.ts +11 -0
- package/dist/tools/playbooks/find-replace.js +56 -0
- package/dist/tools/playbooks/find-replace.js.map +1 -0
- package/dist/tools/playbooks/index.d.ts +63 -0
- package/dist/tools/playbooks/index.js +70 -0
- package/dist/tools/playbooks/index.js.map +1 -0
- package/dist/tools/playbooks/keys-blocklist.d.ts +24 -0
- package/dist/tools/playbooks/keys-blocklist.js +89 -0
- package/dist/tools/playbooks/keys-blocklist.js.map +1 -0
- package/dist/tools/registry.d.ts +40 -0
- package/dist/tools/registry.js +560 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/safety-gate.d.ts +16 -0
- package/dist/tools/safety-gate.js +70 -0
- package/dist/tools/safety-gate.js.map +1 -0
- package/dist/tools/scheduler.d.ts +76 -0
- package/dist/tools/scheduler.js +413 -0
- package/dist/tools/scheduler.js.map +1 -0
- package/dist/tools/shortcuts.d.ts +13 -0
- package/dist/tools/shortcuts.js +205 -0
- package/dist/tools/shortcuts.js.map +1 -0
- package/dist/tools/smart.d.ts +15 -0
- package/dist/tools/smart.js +785 -0
- package/dist/tools/smart.js.map +1 -0
- package/dist/tools/types.d.ts +174 -0
- package/dist/tools/types.js +67 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/tools/window-text.d.ts +15 -0
- package/dist/tools/window-text.js +39 -0
- package/dist/tools/window-text.js.map +1 -0
- package/dist/types.d.ts +122 -0
- package/dist/types.js +41 -0
- package/dist/types.js.map +1 -0
- package/native/Package.swift +38 -0
- package/native/README.md +113 -0
- package/native/Sources/ClawdCursorHelper/main.swift +602 -0
- package/native/Sources/ClawdCursorHost/main.swift +182 -0
- package/native/Sources/PermissionCheck/main.swift +53 -0
- package/native/Sources/ScreenshotHelper/main.swift +219 -0
- package/native/build.sh +139 -0
- package/native/entitlements.plist +12 -0
- package/package.json +115 -0
- package/scripts/banner.ps1 +112 -0
- package/scripts/coord-accuracy.ps1 +140 -0
- package/scripts/coord-uwp.ps1 +80 -0
- package/scripts/edge-glow.ps1 +180 -0
- package/scripts/find-element.ps1 +198 -0
- package/scripts/get-foreground-window.ps1 +71 -0
- package/scripts/get-screen-context.ps1 +183 -0
- package/scripts/get-windows.ps1 +66 -0
- package/scripts/install-panic-hotkey.ps1 +46 -0
- package/scripts/interact-element.ps1 +431 -0
- package/scripts/invoke-element.ps1 +314 -0
- package/scripts/linux/atspi-bridge.py +356 -0
- package/scripts/linux/ocr-recognize.py +154 -0
- package/scripts/mac/_window-picker.jxa +163 -0
- package/scripts/mac/find-element.jxa +0 -0
- package/scripts/mac/find-element.sh +161 -0
- package/scripts/mac/focus-window.jxa +284 -0
- package/scripts/mac/get-focused-element.jxa +102 -0
- package/scripts/mac/get-foreground-window.jxa +173 -0
- package/scripts/mac/get-screen-context.jxa +197 -0
- package/scripts/mac/get-ui-tree.sh +141 -0
- package/scripts/mac/get-windows.jxa +117 -0
- package/scripts/mac/interact-element.sh +235 -0
- package/scripts/mac/invoke-element.jxa +408 -0
- package/scripts/mac/ocr-recognize.swift +124 -0
- package/scripts/ocr-recognize.ps1 +102 -0
- package/scripts/postinstall-native.js +48 -0
- package/scripts/ps-bridge.ps1 +830 -0
- package/scripts/smoke-mcp.ps1 +119 -0
- package/scripts/sync-version.ts +178 -0
- package/scripts/verify-install.js +81 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* PSRunner — Persistent PowerShell UIA bridge.
|
|
4
|
+
*
|
|
5
|
+
* Keeps one powershell.exe alive for the entire session.
|
|
6
|
+
* UI Automation assemblies are loaded once at startup (~800ms).
|
|
7
|
+
* Each subsequent command costs only the actual work — no 200-500ms spawn overhead.
|
|
8
|
+
*
|
|
9
|
+
* Protocol: newline-delimited JSON on stdin/stdout.
|
|
10
|
+
* Send: {"cmd":"invoke-element","processId":123,...}\n
|
|
11
|
+
* Recv: {"success":true,...}\n
|
|
12
|
+
*
|
|
13
|
+
* Commands are serialized (one at a time), queued if a call is in-flight.
|
|
14
|
+
*/
|
|
15
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
18
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
19
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
20
|
+
}
|
|
21
|
+
Object.defineProperty(o, k2, desc);
|
|
22
|
+
}) : (function(o, m, k, k2) {
|
|
23
|
+
if (k2 === undefined) k2 = k;
|
|
24
|
+
o[k2] = m[k];
|
|
25
|
+
}));
|
|
26
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
27
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
28
|
+
}) : function(o, v) {
|
|
29
|
+
o["default"] = v;
|
|
30
|
+
});
|
|
31
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
32
|
+
var ownKeys = function(o) {
|
|
33
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
34
|
+
var ar = [];
|
|
35
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
36
|
+
return ar;
|
|
37
|
+
};
|
|
38
|
+
return ownKeys(o);
|
|
39
|
+
};
|
|
40
|
+
return function (mod) {
|
|
41
|
+
if (mod && mod.__esModule) return mod;
|
|
42
|
+
var result = {};
|
|
43
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
44
|
+
__setModuleDefault(result, mod);
|
|
45
|
+
return result;
|
|
46
|
+
};
|
|
47
|
+
})();
|
|
48
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
+
exports.psRunner = exports.PSRunner = void 0;
|
|
50
|
+
const child_process_1 = require("child_process");
|
|
51
|
+
const readline = __importStar(require("readline"));
|
|
52
|
+
const path = __importStar(require("path"));
|
|
53
|
+
const paths_1 = require("../paths");
|
|
54
|
+
const BRIDGE_SCRIPT = path.join((0, paths_1.getPackageRoot)(), 'scripts', 'ps-bridge.ps1');
|
|
55
|
+
const READY_TIMEOUT = 12000; // initial PS startup + assembly load
|
|
56
|
+
const CALL_TIMEOUT = 20000; // per command (reduced from 45s — PSRunner is fast enough)
|
|
57
|
+
const MAX_QUEUE_SIZE = 100; // backpressure — reject if queue exceeds this
|
|
58
|
+
class PSRunner {
|
|
59
|
+
proc = null;
|
|
60
|
+
rl = null;
|
|
61
|
+
ready = false;
|
|
62
|
+
dead = false;
|
|
63
|
+
queue = [];
|
|
64
|
+
current = null;
|
|
65
|
+
startPromise = null;
|
|
66
|
+
async start() {
|
|
67
|
+
if (this.startPromise)
|
|
68
|
+
return this.startPromise;
|
|
69
|
+
this.startPromise = this._start().catch(err => {
|
|
70
|
+
this.startPromise = null;
|
|
71
|
+
throw err;
|
|
72
|
+
});
|
|
73
|
+
return this.startPromise;
|
|
74
|
+
}
|
|
75
|
+
_start() {
|
|
76
|
+
// Capture reject so the exit handler can settle the startup promise even
|
|
77
|
+
// when the PS bridge exits before it outputs {"ready":true}. Without
|
|
78
|
+
// this, clearTimeout(readyTimer) in the exit handler would leave
|
|
79
|
+
// startPromise as a zombie — never resolved, never rejected — causing
|
|
80
|
+
// every subsequent `await this.startPromise` to hang forever.
|
|
81
|
+
let startReject;
|
|
82
|
+
return new Promise((resolve, reject) => {
|
|
83
|
+
startReject = reject;
|
|
84
|
+
this.dead = false;
|
|
85
|
+
this.ready = false;
|
|
86
|
+
this.proc = (0, child_process_1.spawn)('powershell.exe', [
|
|
87
|
+
'-NoProfile',
|
|
88
|
+
'-NonInteractive',
|
|
89
|
+
'-ExecutionPolicy', 'Bypass',
|
|
90
|
+
'-File', BRIDGE_SCRIPT,
|
|
91
|
+
], { stdio: ['pipe', 'pipe', 'pipe'] });
|
|
92
|
+
this.rl = readline.createInterface({ input: this.proc.stdout });
|
|
93
|
+
const readyTimer = setTimeout(() => {
|
|
94
|
+
reject(new Error('PSRunner: timed out waiting for bridge ready'));
|
|
95
|
+
}, READY_TIMEOUT);
|
|
96
|
+
this.rl.on('line', (line) => {
|
|
97
|
+
line = line.trim();
|
|
98
|
+
if (!line)
|
|
99
|
+
return;
|
|
100
|
+
let data;
|
|
101
|
+
try {
|
|
102
|
+
data = JSON.parse(line);
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (!this.ready) {
|
|
108
|
+
if (data.ready) {
|
|
109
|
+
this.ready = true;
|
|
110
|
+
clearTimeout(readyTimer);
|
|
111
|
+
console.log('[PSBridge] Ready — UIA assemblies loaded');
|
|
112
|
+
resolve();
|
|
113
|
+
}
|
|
114
|
+
else if (data.error) {
|
|
115
|
+
clearTimeout(readyTimer);
|
|
116
|
+
reject(new Error(`PSRunner startup: ${data.error}`));
|
|
117
|
+
}
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
// Deliver to in-flight call
|
|
121
|
+
const call = this.current;
|
|
122
|
+
this.current = null;
|
|
123
|
+
if (call) {
|
|
124
|
+
clearTimeout(call.timer);
|
|
125
|
+
if (data.error)
|
|
126
|
+
call.reject(new Error(data.error));
|
|
127
|
+
else
|
|
128
|
+
call.resolve(data);
|
|
129
|
+
}
|
|
130
|
+
this._drain();
|
|
131
|
+
});
|
|
132
|
+
this.proc.stderr.on('data', (chunk) => {
|
|
133
|
+
const msg = chunk.toString().trim();
|
|
134
|
+
if (msg)
|
|
135
|
+
console.error(`[PSBridge] ${msg}`);
|
|
136
|
+
});
|
|
137
|
+
this.proc.on('exit', (code) => {
|
|
138
|
+
const pending = this.current ? [this.current, ...this.queue] : [...this.queue];
|
|
139
|
+
this.dead = true;
|
|
140
|
+
this.ready = false;
|
|
141
|
+
this.startPromise = null;
|
|
142
|
+
clearTimeout(readyTimer);
|
|
143
|
+
if (pending.length > 0) {
|
|
144
|
+
console.error(`[PSBridge] Process exited (code ${code}) with ${pending.length} pending command(s) — will restart on next call`);
|
|
145
|
+
}
|
|
146
|
+
this.current = null;
|
|
147
|
+
this.queue = [];
|
|
148
|
+
const err = new Error(`PSRunner exited (code ${code})`);
|
|
149
|
+
// Reject the startup promise if the bridge never signalled ready.
|
|
150
|
+
// Previously this was omitted: clearTimeout(readyTimer) disabled the
|
|
151
|
+
// 12-second safety net but no rejection was issued, leaving
|
|
152
|
+
// startPromise as an unsettled zombie. Any awaiter (e.g.
|
|
153
|
+
// getActiveWindow inside key_press) would then hang forever.
|
|
154
|
+
startReject(err);
|
|
155
|
+
for (const c of pending) {
|
|
156
|
+
clearTimeout(c.timer);
|
|
157
|
+
c.reject(err);
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
async run(command) {
|
|
163
|
+
// Auto-start or auto-restart
|
|
164
|
+
if (!this.startPromise || this.dead) {
|
|
165
|
+
if (this.dead)
|
|
166
|
+
console.log('[PSBridge] Restarting crashed bridge process...');
|
|
167
|
+
this.dead = false;
|
|
168
|
+
await this.start();
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
await this.startPromise;
|
|
172
|
+
}
|
|
173
|
+
return new Promise((resolve, reject) => {
|
|
174
|
+
if (this.queue.length >= MAX_QUEUE_SIZE) {
|
|
175
|
+
reject(new Error(`PSRunner queue full (${MAX_QUEUE_SIZE}) — backpressure. Try again later.`));
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
const call = {
|
|
179
|
+
command,
|
|
180
|
+
resolve,
|
|
181
|
+
reject,
|
|
182
|
+
timer: setTimeout(() => {
|
|
183
|
+
if (this.current === call)
|
|
184
|
+
this.current = null;
|
|
185
|
+
console.error(`[PSBridge] Command timeout after ${CALL_TIMEOUT}ms: ${String(command.cmd)}`);
|
|
186
|
+
reject(new Error(`PSRunner timeout: ${String(command.cmd)}`));
|
|
187
|
+
this._drain();
|
|
188
|
+
}, CALL_TIMEOUT),
|
|
189
|
+
};
|
|
190
|
+
this.queue.push(call);
|
|
191
|
+
this._drain();
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
_drain() {
|
|
195
|
+
if (this.current || this.queue.length === 0 || !this.proc || this.dead)
|
|
196
|
+
return;
|
|
197
|
+
this.current = this.queue.shift();
|
|
198
|
+
try {
|
|
199
|
+
const line = JSON.stringify(this.current.command) + '\n';
|
|
200
|
+
this.proc.stdin.write(line);
|
|
201
|
+
}
|
|
202
|
+
catch (err) {
|
|
203
|
+
const call = this.current;
|
|
204
|
+
this.current = null;
|
|
205
|
+
clearTimeout(call.timer);
|
|
206
|
+
call.reject(err);
|
|
207
|
+
this._drain();
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
stop() {
|
|
211
|
+
if (this.proc) {
|
|
212
|
+
try {
|
|
213
|
+
this.proc.stdin.write('EXIT\n');
|
|
214
|
+
}
|
|
215
|
+
catch { }
|
|
216
|
+
setTimeout(() => { try {
|
|
217
|
+
this.proc?.kill();
|
|
218
|
+
}
|
|
219
|
+
catch { } }, 500);
|
|
220
|
+
}
|
|
221
|
+
this.ready = false;
|
|
222
|
+
this.dead = true;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
exports.PSRunner = PSRunner;
|
|
226
|
+
// Singleton — shared across all AccessibilityBridge instances
|
|
227
|
+
exports.psRunner = new PSRunner();
|
|
228
|
+
//# sourceMappingURL=ps-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ps-runner.js","sourceRoot":"","sources":["../../src/platform/ps-runner.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,iDAA2E;AAC3E,mDAAqC;AACrC,2CAA6B;AAC7B,oCAA0C;AAE1C,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,IAAA,sBAAc,GAAE,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;AAC9E,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,qCAAqC;AAClE,MAAM,YAAY,GAAI,KAAK,CAAC,CAAC,2DAA2D;AACxF,MAAM,cAAc,GAAG,GAAG,CAAC,CAAE,8CAA8C;AAS3E,MAAa,QAAQ;IACX,IAAI,GAAkD,IAAI,CAAC;IAC3D,EAAE,GAAwC,IAAI,CAAC;IAC/C,KAAK,GAAI,KAAK,CAAC;IACf,IAAI,GAAK,KAAK,CAAC;IACf,KAAK,GAAkB,EAAE,CAAC;IAC1B,OAAO,GAAuB,IAAI,CAAC;IACnC,YAAY,GAAyB,IAAI,CAAC;IAElD,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,YAAY;YAAE,OAAO,IAAI,CAAC,YAAY,CAAC;QAChD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;YAC5C,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;YACzB,MAAM,GAAG,CAAC;QACZ,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAEO,MAAM;QACZ,yEAAyE;QACzE,sEAAsE;QACtE,iEAAiE;QACjE,sEAAsE;QACtE,8DAA8D;QAC9D,IAAI,WAAkC,CAAC;QAEvC,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC3C,WAAW,GAAG,MAAM,CAAC;YACrB,IAAI,CAAC,IAAI,GAAI,KAAK,CAAC;YACnB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;YAEnB,IAAI,CAAC,IAAI,GAAG,IAAA,qBAAK,EAAC,gBAAgB,EAAE;gBAClC,YAAY;gBACZ,iBAAiB;gBACjB,kBAAkB,EAAE,QAAQ;gBAC5B,OAAO,EAAE,aAAa;aACvB,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;YAExC,IAAI,CAAC,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,MAAO,EAAE,CAAC,CAAC;YAEjE,MAAM,UAAU,GAAG,UAAU,CAAC,GAAG,EAAE;gBACjC,MAAM,CAAC,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC,CAAC;YACpE,CAAC,EAAE,aAAa,CAAC,CAAC;YAElB,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;gBAC1B,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;gBACnB,IAAI,CAAC,IAAI;oBAAE,OAAO;gBAElB,IAAI,IAAS,CAAC;gBACd,IAAI,CAAC;oBAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC;oBAAC,OAAO;gBAAC,CAAC;gBAElD,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;oBAChB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;wBACf,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;wBAClB,YAAY,CAAC,UAAU,CAAC,CAAC;wBACzB,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;wBACxD,OAAO,EAAE,CAAC;oBACZ,CAAC;yBAAM,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;wBACtB,YAAY,CAAC,UAAU,CAAC,CAAC;wBACzB,MAAM,CAAC,IAAI,KAAK,CAAC,qBAAqB,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;oBACvD,CAAC;oBACD,OAAO;gBACT,CAAC;gBAED,4BAA4B;gBAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC;gBAC1B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;gBACpB,IAAI,IAAI,EAAE,CAAC;oBACT,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBACzB,IAAI,IAAI,CAAC,KAAK;wBAAE,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;;wBACnC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBACrC,CAAC;gBACD,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,IAAI,CAAC,MAAO,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;gBAC7C,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;gBACpC,IAAI,GAAG;oBAAE,OAAO,CAAC,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC;YAC9C,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;gBAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC/E,IAAI,CAAC,IAAI,GAAI,IAAI,CAAC;gBAClB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;gBACnB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;gBACzB,YAAY,CAAC,UAAU,CAAC,CAAC;gBACzB,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACvB,OAAO,CAAC,KAAK,CAAC,mCAAmC,IAAI,UAAU,OAAO,CAAC,MAAM,iDAAiD,CAAC,CAAC;gBAClI,CAAC;gBACD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;gBACpB,IAAI,CAAC,KAAK,GAAK,EAAE,CAAC;gBAClB,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,yBAAyB,IAAI,GAAG,CAAC,CAAC;gBACxD,kEAAkE;gBAClE,qEAAqE;gBACrE,4DAA4D;gBAC5D,0DAA0D;gBAC1D,6DAA6D;gBAC7D,WAAW,CAAC,GAAG,CAAC,CAAC;gBACjB,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;oBAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;oBAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAAC,CAAC;YACpE,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,OAAgC;QACxC,6BAA6B;QAC7B,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACpC,IAAI,IAAI,CAAC,IAAI;gBAAE,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;YAC9E,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC;YAClB,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,CAAC,YAAY,CAAC;QAC1B,CAAC;QAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,cAAc,EAAE,CAAC;gBACxC,MAAM,CAAC,IAAI,KAAK,CAAC,wBAAwB,cAAc,oCAAoC,CAAC,CAAC,CAAC;gBAC9F,OAAO;YACT,CAAC;YACD,MAAM,IAAI,GAAgB;gBACxB,OAAO;gBACP,OAAO;gBACP,MAAM;gBACN,KAAK,EAAE,UAAU,CAAC,GAAG,EAAE;oBACrB,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI;wBAAE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;oBAC/C,OAAO,CAAC,KAAK,CAAC,oCAAoC,YAAY,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;oBAC5F,MAAM,CAAC,IAAI,KAAK,CAAC,qBAAqB,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;oBAC9D,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,CAAC,EAAE,YAAY,CAAC;aACjB,CAAC;YACF,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtB,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,MAAM;QACZ,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI;YAAE,OAAO;QAC/E,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAG,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;YACzD,IAAI,CAAC,IAAI,CAAC,KAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC;YAC1B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjB,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,CAAC;IACH,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,IAAI,CAAC;gBAAC,IAAI,CAAC,IAAI,CAAC,KAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;YAClD,UAAU,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;gBAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACjE,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,IAAI,GAAI,IAAI,CAAC;IACpB,CAAC;CACF;AA7JD,4BA6JC;AAED,8DAA8D;AACjD,QAAA,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC"}
|
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PlatformAdapter — single contract for all platform-specific operations.
|
|
3
|
+
*
|
|
4
|
+
* Replaces scattered `if (IS_MAC) ... else ...` branching across 34 files.
|
|
5
|
+
* Each platform implements this interface; business logic stays platform-free.
|
|
6
|
+
*
|
|
7
|
+
* Tranche 1A (v0.8.1-alpha): adds the primitives needed to unblock the
|
|
8
|
+
* Tranche 1B / 2 MCP tools (mouseDown/mouseUp, keyDown/keyUp, middle click,
|
|
9
|
+
* horizontal scroll, window-state / bounds control, display enumeration,
|
|
10
|
+
* waitForElement, widened invokeElement actions, UI-element state flags).
|
|
11
|
+
* Every change is ADDITIVE — existing signatures kept so no caller breaks.
|
|
12
|
+
*/
|
|
13
|
+
export interface ScreenSize {
|
|
14
|
+
/** Physical pixels (what screenshots are captured at). */
|
|
15
|
+
physicalWidth: number;
|
|
16
|
+
physicalHeight: number;
|
|
17
|
+
/** Logical pixels (what mouse coordinates use). */
|
|
18
|
+
logicalWidth: number;
|
|
19
|
+
logicalHeight: number;
|
|
20
|
+
/** Physical / logical (e.g. 2.0 on Retina, 1.0 on standard). */
|
|
21
|
+
dpiRatio: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* A physical display. `getScreenSize()` returns the primary display only —
|
|
25
|
+
* `listDisplays()` returns every connected display so callers can target a
|
|
26
|
+
* specific one for screenshots or mouse coordinates.
|
|
27
|
+
*/
|
|
28
|
+
export interface Display {
|
|
29
|
+
/** Index (0 = primary). Stable per boot. */
|
|
30
|
+
index: number;
|
|
31
|
+
/** Human label (e.g. "Display 1", "Built-in Retina Display"). */
|
|
32
|
+
label: string;
|
|
33
|
+
/** Whether this is the primary / main display. */
|
|
34
|
+
primary: boolean;
|
|
35
|
+
/** Logical bounds — mouse-coordinate space. Can be negative for left-of-primary. */
|
|
36
|
+
bounds: {
|
|
37
|
+
x: number;
|
|
38
|
+
y: number;
|
|
39
|
+
width: number;
|
|
40
|
+
height: number;
|
|
41
|
+
};
|
|
42
|
+
/** Physical (pixel) dimensions. */
|
|
43
|
+
physicalSize: {
|
|
44
|
+
width: number;
|
|
45
|
+
height: number;
|
|
46
|
+
};
|
|
47
|
+
/** Physical / logical scale. */
|
|
48
|
+
dpiRatio: number;
|
|
49
|
+
}
|
|
50
|
+
export interface ScreenshotResult {
|
|
51
|
+
/** PNG image buffer. */
|
|
52
|
+
buffer: Buffer;
|
|
53
|
+
/** Image dimensions (may differ from screen size if resized). */
|
|
54
|
+
width: number;
|
|
55
|
+
height: number;
|
|
56
|
+
/** Multiplier to convert image coords back to physical screen coords. */
|
|
57
|
+
scaleFactor: number;
|
|
58
|
+
}
|
|
59
|
+
export interface WindowInfo {
|
|
60
|
+
title: string;
|
|
61
|
+
processName: string;
|
|
62
|
+
processId: number;
|
|
63
|
+
bounds: {
|
|
64
|
+
x: number;
|
|
65
|
+
y: number;
|
|
66
|
+
width: number;
|
|
67
|
+
height: number;
|
|
68
|
+
};
|
|
69
|
+
isMinimized: boolean;
|
|
70
|
+
/** Platform-opaque handle for re-targeting. */
|
|
71
|
+
handle?: number | string;
|
|
72
|
+
}
|
|
73
|
+
export interface UiElement {
|
|
74
|
+
name: string;
|
|
75
|
+
controlType: string;
|
|
76
|
+
/** Platform subrole when present (macOS AX exposes e.g. "AXSecureTextField",
|
|
77
|
+
* "AXSearchField"); used to detect secureness and refine the role. */
|
|
78
|
+
subrole?: string;
|
|
79
|
+
/** Whether this is a password/secure field — its `value` is withheld. */
|
|
80
|
+
secure?: boolean;
|
|
81
|
+
bounds: {
|
|
82
|
+
x: number;
|
|
83
|
+
y: number;
|
|
84
|
+
width: number;
|
|
85
|
+
height: number;
|
|
86
|
+
};
|
|
87
|
+
/** Optional structured value (e.g. text field contents). */
|
|
88
|
+
value?: string;
|
|
89
|
+
/** Whether the element is enabled and interactable. */
|
|
90
|
+
enabled?: boolean;
|
|
91
|
+
/** Whether the element currently has keyboard focus. */
|
|
92
|
+
focused?: boolean;
|
|
93
|
+
/** Whether the element is currently selected (list items, tabs, radios). */
|
|
94
|
+
selected?: boolean;
|
|
95
|
+
/** Element is in a disabled (grayed-out) state. Opposite of `enabled`. */
|
|
96
|
+
disabled?: boolean;
|
|
97
|
+
/** Element is marked busy (e.g. progress in-flight). */
|
|
98
|
+
busy?: boolean;
|
|
99
|
+
/** Element is off-screen / scrolled out of view. */
|
|
100
|
+
offscreen?: boolean;
|
|
101
|
+
/** Element supports expand/collapse (has an ExpandCollapse a11y pattern). */
|
|
102
|
+
expandable?: boolean;
|
|
103
|
+
/** Current expand state when `expandable` is true. */
|
|
104
|
+
expanded?: boolean;
|
|
105
|
+
/** Platform-opaque automation identifier (UIA AutomationId, AX identifier, AT-SPI name). */
|
|
106
|
+
automationId?: string;
|
|
107
|
+
/** Owning-process id when known. */
|
|
108
|
+
processId?: number;
|
|
109
|
+
/**
|
|
110
|
+
* Human-readable description of the element when its primary `name` is
|
|
111
|
+
* empty. UIA exposes this via `LocalizedControlType` / `HelpText`; AX
|
|
112
|
+
* exposes it via `AXDescription` / `AXRoleDescription`; AT-SPI exposes
|
|
113
|
+
* it via the `description` attribute. Many third-party macOS apps (Xcode
|
|
114
|
+
* in particular) put their visible text in `AXDescription` rather than
|
|
115
|
+
* `AXTitle`, so `name` arrives empty and the element looks anonymous to
|
|
116
|
+
* the agent. Consumers should fall back through `name → description →
|
|
117
|
+
* value → controlType` when rendering. Adapters populate when available;
|
|
118
|
+
* undefined is acceptable (back-compat).
|
|
119
|
+
*
|
|
120
|
+
* Added 0.9.4 for issue #101 bug 5.
|
|
121
|
+
*/
|
|
122
|
+
description?: string;
|
|
123
|
+
}
|
|
124
|
+
export interface PermissionStatus {
|
|
125
|
+
/** Can we send keyboard/mouse events to other apps? */
|
|
126
|
+
input: boolean;
|
|
127
|
+
/** Can we read window contents / accessibility tree? */
|
|
128
|
+
accessibility: boolean;
|
|
129
|
+
/** Can we capture the screen? */
|
|
130
|
+
screenRecording: boolean;
|
|
131
|
+
}
|
|
132
|
+
/** Pointer button — extended in Tranche 1A to include middle click. */
|
|
133
|
+
export type MouseButton = 'left' | 'right' | 'middle';
|
|
134
|
+
/**
|
|
135
|
+
* Result of the pre-click foreground promotion (Win32 WindowFromPoint +
|
|
136
|
+
* SetForegroundWindow). `activated:false` means the OS refused to bring the
|
|
137
|
+
* window at the click point to the foreground (foreground-lock) — the click
|
|
138
|
+
* likely landed on a DIFFERENT window than intended, so the caller must warn
|
|
139
|
+
* and not blindly send keystrokes next. `title`/`processName` identify the
|
|
140
|
+
* window that was actually promoted/clicked.
|
|
141
|
+
*/
|
|
142
|
+
export interface FocusActivation {
|
|
143
|
+
activated: boolean;
|
|
144
|
+
title?: string;
|
|
145
|
+
processName?: string;
|
|
146
|
+
reason?: string;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Scroll direction — extended in Tranche 1A to include horizontal. Windows
|
|
150
|
+
* and macOS native wheel APIs support both axes; Linux X11 uses xdotool
|
|
151
|
+
* buttons 6/7 or nut-js's `scrollLeft/scrollRight`; Wayland is iffy on
|
|
152
|
+
* horizontal and degrades gracefully.
|
|
153
|
+
*/
|
|
154
|
+
export type ScrollDirection = 'up' | 'down' | 'left' | 'right';
|
|
155
|
+
/**
|
|
156
|
+
* Canonical window state verbs. `setWindowState('close')` is a polite
|
|
157
|
+
* close request (WM_CLOSE / AXCloseAction / wmctrl -c) — the app MAY
|
|
158
|
+
* prompt the user (e.g. "Save changes?") and refuse. Callers must not
|
|
159
|
+
* assume the window was actually closed.
|
|
160
|
+
*/
|
|
161
|
+
export type WindowState = 'maximize' | 'minimize' | 'normal' | 'close';
|
|
162
|
+
/**
|
|
163
|
+
* Invoke-element action union. Expanded in Tranche 1A to cover the UIA
|
|
164
|
+
* ExpandCollapse / Toggle / Selection patterns that `ps-bridge.ps1`
|
|
165
|
+
* already implements on Windows and that `invoke-element.jxa` now
|
|
166
|
+
* implements on macOS. Linux returns `{success:false}` until the
|
|
167
|
+
* AT-SPI bridge lands.
|
|
168
|
+
*/
|
|
169
|
+
export type InvokeAction = 'click' | 'focus' | 'set-value' | 'get-value' | 'expand' | 'collapse' | 'toggle' | 'select';
|
|
170
|
+
export interface WaitForElementQuery {
|
|
171
|
+
name?: string;
|
|
172
|
+
controlType?: string;
|
|
173
|
+
processId?: number;
|
|
174
|
+
/** Poll interval in ms (default 250). */
|
|
175
|
+
intervalMs?: number;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Platform-agnostic interface every supported OS implements.
|
|
179
|
+
*
|
|
180
|
+
* Business logic uses this interface and never touches `process.platform`.
|
|
181
|
+
*/
|
|
182
|
+
export interface PlatformAdapter {
|
|
183
|
+
/** OS family this adapter handles. */
|
|
184
|
+
readonly platform: 'darwin' | 'win32' | 'linux';
|
|
185
|
+
/**
|
|
186
|
+
* Optional environment hint — Linux sets this to 'wayland' or 'x11' so
|
|
187
|
+
* callers can surface graceful "not supported on Wayland" errors for
|
|
188
|
+
* known-broken primitives (cursor queries, some global hotkeys).
|
|
189
|
+
* Undefined on Windows and macOS.
|
|
190
|
+
*/
|
|
191
|
+
readonly environment?: 'wayland' | 'x11';
|
|
192
|
+
/** One-time setup (warm caches, start helpers). */
|
|
193
|
+
init(): Promise<void>;
|
|
194
|
+
/** Cleanup on shutdown. */
|
|
195
|
+
shutdown(): Promise<void>;
|
|
196
|
+
checkPermissions(): Promise<PermissionStatus>;
|
|
197
|
+
requestPermissions(): Promise<PermissionStatus>;
|
|
198
|
+
/** Get the primary display geometry. */
|
|
199
|
+
getScreenSize(): Promise<ScreenSize>;
|
|
200
|
+
/**
|
|
201
|
+
* List ALL connected displays. Tranche 1A primitive — unblocks
|
|
202
|
+
* multi-monitor-aware screenshot and mouse targeting. Primary display
|
|
203
|
+
* is always at index 0.
|
|
204
|
+
*/
|
|
205
|
+
listDisplays(): Promise<Display[]>;
|
|
206
|
+
/**
|
|
207
|
+
* Capture the full screen as PNG. Optionally resize to maxWidth.
|
|
208
|
+
* `displayIndex` (Tranche 1A) selects a specific display — 0 (default)
|
|
209
|
+
* is primary. Passing an out-of-range index falls back to primary.
|
|
210
|
+
*/
|
|
211
|
+
screenshot(opts?: {
|
|
212
|
+
maxWidth?: number;
|
|
213
|
+
displayIndex?: number;
|
|
214
|
+
}): Promise<ScreenshotResult>;
|
|
215
|
+
/** Capture a region of the screen. */
|
|
216
|
+
screenshotRegion(x: number, y: number, w: number, h: number): Promise<ScreenshotResult>;
|
|
217
|
+
listWindows(): Promise<WindowInfo[]>;
|
|
218
|
+
getActiveWindow(): Promise<WindowInfo | null>;
|
|
219
|
+
focusWindow(query: {
|
|
220
|
+
processName?: string;
|
|
221
|
+
processId?: number;
|
|
222
|
+
title?: string;
|
|
223
|
+
}): Promise<boolean>;
|
|
224
|
+
/**
|
|
225
|
+
* Legacy shim — preserved for back-compat. New code should call
|
|
226
|
+
* `setWindowState('maximize')`. Default behavior unchanged.
|
|
227
|
+
*/
|
|
228
|
+
maximizeWindow(): Promise<void>;
|
|
229
|
+
/**
|
|
230
|
+
* Canonical window-state control. Semantics (Tranche 1A):
|
|
231
|
+
* - 'maximize' — full-working-area size
|
|
232
|
+
* - 'minimize' — hide to taskbar/Dock
|
|
233
|
+
* - 'normal' — restore from minimized/maximized to previous bounds
|
|
234
|
+
* - 'close' — polite close request; app may prompt / refuse
|
|
235
|
+
*
|
|
236
|
+
* Target: the currently-focused window unless `query` is supplied.
|
|
237
|
+
* Returns true when the request was accepted, NOT when the state
|
|
238
|
+
* transition completed.
|
|
239
|
+
*/
|
|
240
|
+
setWindowState(state: WindowState, query?: {
|
|
241
|
+
processName?: string;
|
|
242
|
+
processId?: number;
|
|
243
|
+
title?: string;
|
|
244
|
+
}): Promise<boolean>;
|
|
245
|
+
/**
|
|
246
|
+
* Set the foreground (or matched) window's logical-pixel bounds.
|
|
247
|
+
* Returns true when the request was accepted. No-op where the WM
|
|
248
|
+
* refuses programmatic move/resize (some tiling Linux WMs).
|
|
249
|
+
*/
|
|
250
|
+
setWindowBounds(bounds: {
|
|
251
|
+
x?: number;
|
|
252
|
+
y?: number;
|
|
253
|
+
width?: number;
|
|
254
|
+
height?: number;
|
|
255
|
+
}, query?: {
|
|
256
|
+
processName?: string;
|
|
257
|
+
processId?: number;
|
|
258
|
+
title?: string;
|
|
259
|
+
}): Promise<boolean>;
|
|
260
|
+
getUiTree(processId?: number): Promise<UiElement[]>;
|
|
261
|
+
findElements(query: {
|
|
262
|
+
name?: string;
|
|
263
|
+
controlType?: string;
|
|
264
|
+
processId?: number;
|
|
265
|
+
}): Promise<UiElement[]>;
|
|
266
|
+
getFocusedElement(): Promise<UiElement | null>;
|
|
267
|
+
/**
|
|
268
|
+
* Invoke an accessibility action on a named element. Action union
|
|
269
|
+
* widened in Tranche 1A. Platforms that don't support a given action
|
|
270
|
+
* return `{ success:false }` — no throw.
|
|
271
|
+
*/
|
|
272
|
+
invokeElement(query: {
|
|
273
|
+
name?: string;
|
|
274
|
+
controlType?: string;
|
|
275
|
+
processId?: number;
|
|
276
|
+
action?: InvokeAction;
|
|
277
|
+
value?: string;
|
|
278
|
+
}): Promise<{
|
|
279
|
+
success: boolean;
|
|
280
|
+
bounds?: {
|
|
281
|
+
x: number;
|
|
282
|
+
y: number;
|
|
283
|
+
width: number;
|
|
284
|
+
height: number;
|
|
285
|
+
};
|
|
286
|
+
/** Action-specific payload, e.g. `{ value }` for get-value, `{ toggleState }` for toggle. */
|
|
287
|
+
data?: Record<string, unknown>;
|
|
288
|
+
}>;
|
|
289
|
+
/**
|
|
290
|
+
* Poll for an element to appear. Returns the first matching element or
|
|
291
|
+
* null when `timeoutMs` elapses. Useful for waiting out transient UI
|
|
292
|
+
* (dialogs, spinners). Tranche 1A primitive — lifted from
|
|
293
|
+
* `action-router.ts`'s internal `waitForElement` helper.
|
|
294
|
+
*/
|
|
295
|
+
waitForElement(query: WaitForElementQuery, timeoutMs: number): Promise<UiElement | null>;
|
|
296
|
+
/** All coords are in LOGICAL pixels (mouse coordinate space).
|
|
297
|
+
* Returns a FocusActivation describing the window brought to the foreground
|
|
298
|
+
* at the click point (when the platform verifies it) so callers can WARN on
|
|
299
|
+
* a failed/ wrong-window activation; void/undefined when not verifiable. */
|
|
300
|
+
mouseClick(x: number, y: number, opts?: {
|
|
301
|
+
button?: MouseButton;
|
|
302
|
+
count?: number;
|
|
303
|
+
}): Promise<FocusActivation | void>;
|
|
304
|
+
mouseMove(x: number, y: number): Promise<void>;
|
|
305
|
+
/**
|
|
306
|
+
* Move relative to the current cursor position. On Wayland where
|
|
307
|
+
* cursor-position queries are blocked, implementations SHOULD cache
|
|
308
|
+
* the last target from `mouseMove`/`mouseClick` and offset from there;
|
|
309
|
+
* if no cache is available, they return without error and log a
|
|
310
|
+
* graceful-degradation warning.
|
|
311
|
+
*/
|
|
312
|
+
mouseMoveRelative(dx: number, dy: number): Promise<void>;
|
|
313
|
+
mouseDrag(x1: number, y1: number, x2: number, y2: number): Promise<void>;
|
|
314
|
+
mouseScroll(x: number, y: number, direction: ScrollDirection, amount?: number): Promise<void>;
|
|
315
|
+
/**
|
|
316
|
+
* Press a button without releasing. Pairs with `mouseUp`. Enables:
|
|
317
|
+
* - Hold modifier + click (Ctrl+click, Shift+click selection)
|
|
318
|
+
* - Multi-point drags (mouseDown at A, mouseMove through path, mouseUp at B)
|
|
319
|
+
* - Press-and-hold gestures
|
|
320
|
+
*/
|
|
321
|
+
mouseDown(button?: MouseButton): Promise<void>;
|
|
322
|
+
/** Release a previously-pressed button. No-op if nothing pressed. */
|
|
323
|
+
mouseUp(button?: MouseButton): Promise<void>;
|
|
324
|
+
typeText(text: string): Promise<void>;
|
|
325
|
+
keyPress(combo: PortableKeyCombo): Promise<void>;
|
|
326
|
+
/**
|
|
327
|
+
* Press a key without releasing. Pairs with `keyUp`. Enables:
|
|
328
|
+
* - Hold shift while clicking
|
|
329
|
+
* - Gaming-style chord input
|
|
330
|
+
* - OS shortcuts that require precise down/up timing
|
|
331
|
+
*
|
|
332
|
+
* `key` accepts the same tokens as `keyPress` (e.g. "shift", "Return",
|
|
333
|
+
* "F5", "a"). macOS implementation uses `System Events` "key down"; Win
|
|
334
|
+
* and Linux use nut-js `keyboard.pressKey`.
|
|
335
|
+
*/
|
|
336
|
+
keyDown(key: PortableKeyCombo): Promise<void>;
|
|
337
|
+
/** Release a previously-pressed key. No-op if not currently down. */
|
|
338
|
+
keyUp(key: PortableKeyCombo): Promise<void>;
|
|
339
|
+
readClipboard(): Promise<string>;
|
|
340
|
+
writeClipboard(text: string): Promise<void>;
|
|
341
|
+
/**
|
|
342
|
+
* Convenience wrapper around `launchApp`. Platform adapters keep this
|
|
343
|
+
* alias-data-agnostic — they DO NOT consult `APP_ALIASES`. Cross-OS
|
|
344
|
+
* name mapping (e.g. Windows "Notepad" → mac "TextEdit") and UWP /
|
|
345
|
+
* executable / searchTerm hints belong in the caller (the agent's
|
|
346
|
+
* `open_app` tool, the router's `handleOpenApp`), which resolves the
|
|
347
|
+
* alias and forwards the data through `launchApp` opts.
|
|
348
|
+
*/
|
|
349
|
+
openApp(name: string, opts?: {
|
|
350
|
+
alwaysNewInstance?: boolean;
|
|
351
|
+
}): Promise<{
|
|
352
|
+
pid?: number;
|
|
353
|
+
title?: string;
|
|
354
|
+
}>;
|
|
355
|
+
launchApp(name: string, opts?: {
|
|
356
|
+
alwaysNewInstance?: boolean;
|
|
357
|
+
url?: string;
|
|
358
|
+
cwd?: string;
|
|
359
|
+
/** Windows UWP AppsFolder ID. Ignored on macOS and Linux. */
|
|
360
|
+
uwpAppId?: string;
|
|
361
|
+
/**
|
|
362
|
+
* Human-friendly term used when the platform falls back to its native
|
|
363
|
+
* search launcher (Windows Start Menu, macOS Spotlight). When omitted,
|
|
364
|
+
* the launcher uses `name` with the `.exe` / `.app` suffix stripped —
|
|
365
|
+
* which works for most apps but fails for cases like `msedge.exe`
|
|
366
|
+
* where the binary name isn't indexed (Windows Search would surface
|
|
367
|
+
* Microsoft Store as the closest match instead of Microsoft Edge).
|
|
368
|
+
* `APP_ALIASES` provides a curated `searchTerm` per app for this.
|
|
369
|
+
*/
|
|
370
|
+
searchTerm?: string;
|
|
371
|
+
/**
|
|
372
|
+
* Skip the Start-Menu / search-launcher fallback (Windows). When the
|
|
373
|
+
* direct launch doesn't surface a window, return `{}` instead of typing
|
|
374
|
+
* the name into the OS search box. Used by `open_file` for a path, where
|
|
375
|
+
* the fallback would type "explorer" and open File Explorer at **Home**
|
|
376
|
+
* instead of the requested folder — a false "Opened" with a side effect.
|
|
377
|
+
*/
|
|
378
|
+
noStartMenuFallback?: boolean;
|
|
379
|
+
}): Promise<{
|
|
380
|
+
pid?: number;
|
|
381
|
+
title?: string;
|
|
382
|
+
handle?: number | string;
|
|
383
|
+
}>;
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Portable key combo spec — uses semantic modifiers, not platform names.
|
|
387
|
+
*
|
|
388
|
+
* "mod" resolves to Cmd on macOS, Ctrl on Windows/Linux.
|
|
389
|
+
* "alt" stays "alt" on Windows/Linux, becomes "option" on macOS at the OS level.
|
|
390
|
+
*
|
|
391
|
+
* Examples:
|
|
392
|
+
* "mod+s" — save (Cmd+S on mac, Ctrl+S elsewhere)
|
|
393
|
+
* "mod+shift+t" — reopen tab
|
|
394
|
+
* "Return" — single key
|
|
395
|
+
* "shift+Tab" — modifier + key
|
|
396
|
+
*/
|
|
397
|
+
export type PortableKeyCombo = string;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* PlatformAdapter — single contract for all platform-specific operations.
|
|
4
|
+
*
|
|
5
|
+
* Replaces scattered `if (IS_MAC) ... else ...` branching across 34 files.
|
|
6
|
+
* Each platform implements this interface; business logic stays platform-free.
|
|
7
|
+
*
|
|
8
|
+
* Tranche 1A (v0.8.1-alpha): adds the primitives needed to unblock the
|
|
9
|
+
* Tranche 1B / 2 MCP tools (mouseDown/mouseUp, keyDown/keyUp, middle click,
|
|
10
|
+
* horizontal scroll, window-state / bounds control, display enumeration,
|
|
11
|
+
* waitForElement, widened invokeElement actions, UI-element state flags).
|
|
12
|
+
* Every change is ADDITIVE — existing signatures kept so no caller breaks.
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/platform/types.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG"}
|