@aurora-foundation/obsidian-next 0.4.7 → 0.4.9
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 +23 -0
- package/LICENSE +628 -190
- package/README.md +23 -9
- package/dist/auditLog-6WDBDNYL.js +8 -0
- package/dist/auditLog-HGPVDSDC.js +8 -0
- package/dist/auditLog-TDIKFBM4.js +8 -0
- package/dist/auditLog-XC2KY3ZZ.js +8 -0
- package/dist/chunk-2I235WNB.js +133 -0
- package/dist/chunk-2JWDGXTR.js +42 -0
- package/dist/chunk-2NOB6W2B.js +133 -0
- package/dist/chunk-3LFKVKKL.js +7199 -0
- package/dist/chunk-3U6WHPDX.js +4695 -0
- package/dist/chunk-3UCL6RYE.js +7272 -0
- package/dist/chunk-4GN2UQLI.js +130 -0
- package/dist/chunk-4MW33MZD.js +516 -0
- package/dist/chunk-4PUJBUKZ.js +4716 -0
- package/dist/chunk-4QHK6H6O.js +130 -0
- package/dist/chunk-55CQIHCO.js +133 -0
- package/dist/chunk-5LWINFWI.js +676 -0
- package/dist/chunk-5OKGLNQW.js +439 -0
- package/dist/chunk-5T6ETZEO.js +6183 -0
- package/dist/chunk-5WGIFUVL.js +4234 -0
- package/dist/chunk-66EW47T3.js +4237 -0
- package/dist/chunk-6TXUOTT2.js +581 -0
- package/dist/chunk-6YUYSYDA.js +130 -0
- package/dist/chunk-74VPNFMX.js +133 -0
- package/dist/chunk-77CGJRGV.js +6188 -0
- package/dist/chunk-7DS3VT4C.js +7135 -0
- package/dist/chunk-7FHX3VBT.js +133 -0
- package/dist/chunk-7MHF56YU.js +6178 -0
- package/dist/chunk-ABLPMV7G.js +133 -0
- package/dist/chunk-B77K6OQZ.js +687 -0
- package/dist/chunk-BKOXH66O.js +133 -0
- package/dist/chunk-BPP76UN2.js +130 -0
- package/dist/chunk-C4D56GRC.js +5936 -0
- package/dist/chunk-CCDPY4WE.js +370 -0
- package/dist/chunk-CHNVBJN3.js +7272 -0
- package/dist/chunk-CKBZI576.js +7229 -0
- package/dist/chunk-CW5HBSJ2.js +7198 -0
- package/dist/chunk-DGHDJEY7.js +133 -0
- package/dist/chunk-DPNIQWKZ.js +439 -0
- package/dist/chunk-DU4T3V2T.js +214 -0
- package/dist/chunk-DV3WFKNB.js +4679 -0
- package/dist/chunk-DZI2OVN2.js +516 -0
- package/dist/chunk-E45VILML.js +7198 -0
- package/dist/chunk-ECEUUYXC.js +7199 -0
- package/dist/chunk-EJRRSHPW.js +685 -0
- package/dist/chunk-EMBMLZFE.js +370 -0
- package/dist/chunk-EPG5V5OO.js +285 -0
- package/dist/chunk-F2R4HXXW.js +130 -0
- package/dist/chunk-FK6N66ES.js +581 -0
- package/dist/chunk-G3CZKGYA.js +197 -0
- package/dist/chunk-GUUPG4A7.js +7111 -0
- package/dist/chunk-HBAAUGUN.js +7230 -0
- package/dist/chunk-HHFJMK2Q.js +6177 -0
- package/dist/chunk-HINRQTCZ.js +196 -0
- package/dist/chunk-HRKJ3R2U.js +288 -0
- package/dist/chunk-HWVK4CVE.js +439 -0
- package/dist/chunk-JEYSADNZ.js +581 -0
- package/dist/chunk-JNEIL7UN.js +4252 -0
- package/dist/chunk-JTWSK277.js +676 -0
- package/dist/chunk-K4CHTTCJ.js +942 -0
- package/dist/chunk-K7R5KUDS.js +4695 -0
- package/dist/chunk-KNJFOURE.js +7151 -0
- package/dist/chunk-KY22FIT3.js +7256 -0
- package/dist/chunk-L2OTIJSF.js +4228 -0
- package/dist/chunk-LEEBUHP6.js +4655 -0
- package/dist/chunk-LK7UP2T7.js +130 -0
- package/dist/chunk-LPGNO3PK.js +284 -0
- package/dist/chunk-LYQYJMWS.js +133 -0
- package/dist/chunk-MBYFJXR3.js +130 -0
- package/dist/chunk-N3WX44L3.js +130 -0
- package/dist/chunk-N6AQWES3.js +6197 -0
- package/dist/chunk-NW4XSTQZ.js +130 -0
- package/dist/chunk-NWG2XURH.js +130 -0
- package/dist/chunk-O3GF3LJD.js +6142 -0
- package/dist/chunk-OHP5LD3Y.js +6188 -0
- package/dist/chunk-P5PQSFZT.js +6182 -0
- package/dist/chunk-PAADOWNP.js +130 -0
- package/dist/chunk-PERGND7L.js +7213 -0
- package/dist/chunk-PWA7V4XX.js +179 -0
- package/dist/chunk-QGCWEP6L.js +7111 -0
- package/dist/chunk-QVT2IHNJ.js +175 -0
- package/dist/chunk-QZNGYPMS.js +6161 -0
- package/dist/chunk-R6P2E2ZQ.js +207 -0
- package/dist/chunk-ROSDMGIL.js +4679 -0
- package/dist/chunk-RQZP7IKG.js +196 -0
- package/dist/chunk-RUQSPX3U.js +133 -0
- package/dist/chunk-S3BYHP5M.js +130 -0
- package/dist/chunk-S6GNETVE.js +438 -0
- package/dist/chunk-SDT2ZE2R.js +133 -0
- package/dist/chunk-SHQBXJFC.js +6166 -0
- package/dist/chunk-TJNISYTE.js +42 -0
- package/dist/chunk-TJW74HFF.js +130 -0
- package/dist/chunk-TPP72DTK.js +7096 -0
- package/dist/chunk-UOESII6R.js +42 -0
- package/dist/chunk-UWEDGLYJ.js +6142 -0
- package/dist/chunk-V5FYNAFX.js +133 -0
- package/dist/chunk-VPURF6UT.js +7198 -0
- package/dist/chunk-VQH6LWIZ.js +6184 -0
- package/dist/chunk-VS22YVX6.js +7111 -0
- package/dist/chunk-VSF5KBW7.js +367 -0
- package/dist/chunk-VV3JMCKY.js +214 -0
- package/dist/chunk-W5L7HOE3.js +133 -0
- package/dist/chunk-WFEVQISK.js +676 -0
- package/dist/chunk-WJZPSCEP.js +516 -0
- package/dist/chunk-WLV4MKEF.js +16 -0
- package/dist/chunk-WSEVQFFI.js +5428 -0
- package/dist/chunk-X7N2RNR3.js +5428 -0
- package/dist/chunk-XKZNMRNO.js +133 -0
- package/dist/chunk-Y7BVEC36.js +130 -0
- package/dist/chunk-YG7YSNNU.js +4226 -0
- package/dist/chunk-YHM62466.js +261 -0
- package/dist/chunk-YLTYJLDZ.js +7208 -0
- package/dist/chunk-YPMJD4YE.js +56 -0
- package/dist/chunk-YTX3FU2A.js +7199 -0
- package/dist/chunk-ZEQ3EBBN.js +214 -0
- package/dist/chunk-ZIWLQSLK.js +42 -0
- package/dist/chunk-ZJELNTEO.js +516 -0
- package/dist/chunk-ZOSSVNGK.js +370 -0
- package/dist/config-EYK32F2E.js +10 -0
- package/dist/config-FJPPPYTY.js +10 -0
- package/dist/config-VAHPVILX.js +10 -0
- package/dist/context-2YGE4U75.js +10 -0
- package/dist/context-5UFVYKES.js +9 -0
- package/dist/context-ANZF4J72.js +10 -0
- package/dist/context-GLUNCUBQ.js +10 -0
- package/dist/context-M5ULPZKQ.js +10 -0
- package/dist/context-NYOIRZKV.js +10 -0
- package/dist/context-YP2REI6A.js +10 -0
- package/dist/database-MP2JBLMF.js +8 -0
- package/dist/index.js +6177 -4688
- package/dist/keyManager-P2SZONKE.js +8 -0
- package/dist/mcp/index.js +127 -47
- package/dist/memory-BPGJAL4J.js +13 -0
- package/dist/memory-FRQOUI6W.js +13 -0
- package/dist/memory-OAMK27IZ.js +13 -0
- package/dist/memory-OZ734ALL.js +13 -0
- package/dist/memory-PQ2EWRMU.js +13 -0
- package/dist/memory-PXL45M6W.js +13 -0
- package/dist/memory-QZTBTYPH.js +13 -0
- package/dist/migrations-TLJ3WRVW.js +188 -0
- package/dist/resume-2NHDK6EI.js +17 -0
- package/dist/resume-44L2PDB2.js +17 -0
- package/dist/resume-4MXIWUJO.js +7 -0
- package/dist/resume-72VJX66I.js +17 -0
- package/dist/resume-7ZW4XM3B.js +15 -0
- package/dist/resume-AZHYQ657.js +17 -0
- package/dist/resume-CNLXSYHV.js +17 -0
- package/dist/resume-DPN4Q777.js +16 -0
- package/dist/resume-DSFHVNPI.js +15 -0
- package/dist/resume-GHLQJJTO.js +17 -0
- package/dist/resume-HJ6SBWTF.js +17 -0
- package/dist/resume-HRLYHY2L.js +17 -0
- package/dist/resume-ISIQFKO6.js +17 -0
- package/dist/resume-JQDEA6PS.js +15 -0
- package/dist/resume-KP3Y3Y7P.js +17 -0
- package/dist/resume-M4KHR5OI.js +17 -0
- package/dist/resume-N62OAMBG.js +17 -0
- package/dist/resume-NNMA5POT.js +17 -0
- package/dist/resume-ODYT3J4H.js +17 -0
- package/dist/resume-PCFJXA5O.js +17 -0
- package/dist/resume-PLF4XGBD.js +15 -0
- package/dist/resume-Q2PFX57V.js +17 -0
- package/dist/resume-QB4XI2J5.js +17 -0
- package/dist/resume-R5MFTUPF.js +17 -0
- package/dist/resume-SVA7223Z.js +17 -0
- package/dist/resume-TYKKDJZI.js +17 -0
- package/dist/resume-XIS45HKV.js +17 -0
- package/dist/resume-YCSEJTU7.js +17 -0
- package/dist/resume-YD76GI2J.js +15 -0
- package/dist/resume-YDN7EL77.js +17 -0
- package/dist/resume-YE7DB4ZA.js +17 -0
- package/dist/resume-YKAKOXWV.js +15 -0
- package/dist/resume-ZHBCVFDY.js +17 -0
- package/dist/scheduler-2CK24A2Q.js +14 -0
- package/dist/scheduler-7OAF2XKX.js +14 -0
- package/dist/scheduler-AS23AAB5.js +14 -0
- package/dist/scheduler-PCOYQJA5.js +14 -0
- package/dist/scheduler-V2ECBQPK.js +14 -0
- package/dist/scheduler-VEWZ6L7V.js +13 -0
- package/dist/scheduler-W37QMGDQ.js +14 -0
- package/dist/session-2E2JKPD7.js +15 -0
- package/dist/session-2VSF257B.js +14 -0
- package/dist/session-4APFTDJU.js +14 -0
- package/dist/session-5YS5LNNL.js +16 -0
- package/dist/session-6MO5ZPOB.js +16 -0
- package/dist/session-6XMGPRTQ.js +14 -0
- package/dist/session-7DJR77R7.js +16 -0
- package/dist/session-7DQHPWTR.js +14 -0
- package/dist/session-ADKIQCR5.js +16 -0
- package/dist/session-AOGH2GGI.js +16 -0
- package/dist/session-C4W6GDYG.js +16 -0
- package/dist/session-DCGNGGMV.js +14 -0
- package/dist/session-F5JKZAN2.js +16 -0
- package/dist/session-G6F3O2FQ.js +16 -0
- package/dist/session-GFBSARRO.js +16 -0
- package/dist/session-H5IWAIUI.js +16 -0
- package/dist/session-IPFA6AHC.js +14 -0
- package/dist/session-IWG2UOAX.js +14 -0
- package/dist/session-KJ2K4Y4M.js +14 -0
- package/dist/session-KPXFBW6Q.js +14 -0
- package/dist/session-KR256UL5.js +16 -0
- package/dist/session-M72LJXPR.js +16 -0
- package/dist/session-MBK3FODN.js +14 -0
- package/dist/session-MOUFAU7G.js +16 -0
- package/dist/session-NRC6ZXFQ.js +16 -0
- package/dist/session-NRPQMV4K.js +16 -0
- package/dist/session-O5IFFJZQ.js +14 -0
- package/dist/session-OF5BGKDE.js +16 -0
- package/dist/session-OGRZMIM7.js +14 -0
- package/dist/session-OJOFAJG3.js +16 -0
- package/dist/session-OKU4N3SP.js +16 -0
- package/dist/session-P2VAOSFB.js +14 -0
- package/dist/session-PKOVZD4M.js +16 -0
- package/dist/session-POAIMUVN.js +16 -0
- package/dist/session-PSHFONFE.js +16 -0
- package/dist/session-QKYVVZFV.js +16 -0
- package/dist/session-QPWGBMUS.js +14 -0
- package/dist/session-R5UG5PZR.js +14 -0
- package/dist/session-RAY6BZRQ.js +16 -0
- package/dist/session-S3VATHMU.js +16 -0
- package/dist/session-SYTD7RHW.js +14 -0
- package/dist/session-UHMMVO4J.js +16 -0
- package/dist/session-WEX5K3ZY.js +14 -0
- package/dist/session-XFLOXGU3.js +14 -0
- package/dist/session-XV2A4HHG.js +14 -0
- package/dist/settings-3VPJYD4D.js +8 -0
- package/dist/settings-GZTJJTBK.js +8 -0
- package/dist/settings-YKJFSKMO.js +8 -0
- package/dist/shell-FM34624T.js +8 -0
- package/package.json +14 -4
|
@@ -0,0 +1,687 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ScreenshotError,
|
|
3
|
+
shell
|
|
4
|
+
} from "./chunk-YPMJD4YE.js";
|
|
5
|
+
|
|
6
|
+
// src/computer/screenshot.ts
|
|
7
|
+
import * as fs from "fs";
|
|
8
|
+
var MAX_LONG_EDGE = 1568;
|
|
9
|
+
var MAX_PIXELS = 115e4;
|
|
10
|
+
async function getDisplayDimensions() {
|
|
11
|
+
try {
|
|
12
|
+
try {
|
|
13
|
+
const { stdout } = await shell.execute(
|
|
14
|
+
"system_profiler SPDisplaysDataType | grep Resolution | head -1 | awk '{print $2, $4}'"
|
|
15
|
+
);
|
|
16
|
+
const parts = stdout.trim().split(/\s+/);
|
|
17
|
+
if (parts.length >= 2) {
|
|
18
|
+
const width = parseInt(parts[0], 10);
|
|
19
|
+
const height = parseInt(parts[1], 10);
|
|
20
|
+
if (width > 0 && height > 0) {
|
|
21
|
+
return { width, height };
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
} catch {
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
const { stdout } = await shell.execute(
|
|
28
|
+
`osascript -e 'tell application "Finder" to get bounds of window of desktop'`
|
|
29
|
+
);
|
|
30
|
+
const parts = stdout.trim().split(",").map((p) => parseInt(p.trim(), 10));
|
|
31
|
+
if (parts.length === 4 && parts[2] > 0 && parts[3] > 0) {
|
|
32
|
+
return { width: parts[2], height: parts[3] };
|
|
33
|
+
}
|
|
34
|
+
} catch {
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
const { stdout } = await shell.execute(
|
|
38
|
+
"screenresolution get 2>/dev/null || echo ''"
|
|
39
|
+
);
|
|
40
|
+
const match = stdout.match(/(\d+)\s*x\s*(\d+)/);
|
|
41
|
+
if (match) {
|
|
42
|
+
return {
|
|
43
|
+
width: parseInt(match[1], 10),
|
|
44
|
+
height: parseInt(match[2], 10)
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
} catch {
|
|
48
|
+
}
|
|
49
|
+
} catch (error) {
|
|
50
|
+
}
|
|
51
|
+
return { width: 1920, height: 1080 };
|
|
52
|
+
}
|
|
53
|
+
function calculateScaleForAPI(width, height) {
|
|
54
|
+
const longEdge = Math.max(width, height);
|
|
55
|
+
const totalPixels = width * height;
|
|
56
|
+
const longEdgeScale = MAX_LONG_EDGE / longEdge;
|
|
57
|
+
const totalPixelsScale = Math.sqrt(MAX_PIXELS / totalPixels);
|
|
58
|
+
return Math.min(1, longEdgeScale, totalPixelsScale);
|
|
59
|
+
}
|
|
60
|
+
async function takeScreenshot(captureCursor = false) {
|
|
61
|
+
const screenshotPath = `/tmp/screenshot-${Date.now()}.png`;
|
|
62
|
+
const flags = captureCursor ? "-x -C" : "-x";
|
|
63
|
+
try {
|
|
64
|
+
await shell.execute(`screencapture ${flags} ${screenshotPath}`);
|
|
65
|
+
const imageBuffer = fs.readFileSync(screenshotPath);
|
|
66
|
+
return imageBuffer.toString("base64");
|
|
67
|
+
} catch (error) {
|
|
68
|
+
throw new ScreenshotError("Failed to capture screenshot", error);
|
|
69
|
+
} finally {
|
|
70
|
+
if (fs.existsSync(screenshotPath)) {
|
|
71
|
+
fs.unlinkSync(screenshotPath);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async function takeScreenshotForAPI(captureCursor = false, targetWidth, targetHeight) {
|
|
76
|
+
const screenshotPath = `/tmp/screenshot-${Date.now()}.png`;
|
|
77
|
+
const resizedPath = `/tmp/screenshot-resized-${Date.now()}.png`;
|
|
78
|
+
const flags = captureCursor ? "-x -C" : "-x";
|
|
79
|
+
try {
|
|
80
|
+
await shell.execute(`screencapture ${flags} ${screenshotPath}`);
|
|
81
|
+
const { stdout: sizeOutput } = await shell.execute(
|
|
82
|
+
`sips -g pixelWidth -g pixelHeight ${screenshotPath} | tail -2`
|
|
83
|
+
);
|
|
84
|
+
const widthMatch = sizeOutput.match(/pixelWidth:\s*(\d+)/);
|
|
85
|
+
const heightMatch = sizeOutput.match(/pixelHeight:\s*(\d+)/);
|
|
86
|
+
const originalWidth = widthMatch ? parseInt(widthMatch[1], 10) : 1920;
|
|
87
|
+
const originalHeight = heightMatch ? parseInt(heightMatch[1], 10) : 1080;
|
|
88
|
+
const scale = calculateScaleForAPI(originalWidth, originalHeight);
|
|
89
|
+
const finalWidth = targetWidth || Math.floor(originalWidth * scale);
|
|
90
|
+
const finalHeight = targetHeight || Math.floor(originalHeight * scale);
|
|
91
|
+
if (scale < 1) {
|
|
92
|
+
await shell.execute(
|
|
93
|
+
`sips -z ${finalHeight} ${finalWidth} ${screenshotPath} --out ${resizedPath}`
|
|
94
|
+
);
|
|
95
|
+
const imageBuffer = fs.readFileSync(resizedPath);
|
|
96
|
+
return {
|
|
97
|
+
base64: imageBuffer.toString("base64"),
|
|
98
|
+
width: finalWidth,
|
|
99
|
+
height: finalHeight,
|
|
100
|
+
scale
|
|
101
|
+
};
|
|
102
|
+
} else {
|
|
103
|
+
const imageBuffer = fs.readFileSync(screenshotPath);
|
|
104
|
+
return {
|
|
105
|
+
base64: imageBuffer.toString("base64"),
|
|
106
|
+
width: originalWidth,
|
|
107
|
+
height: originalHeight,
|
|
108
|
+
scale: 1
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
} catch (error) {
|
|
112
|
+
throw new ScreenshotError("Failed to capture/resize screenshot", error);
|
|
113
|
+
} finally {
|
|
114
|
+
for (const p of [screenshotPath, resizedPath]) {
|
|
115
|
+
if (fs.existsSync(p)) {
|
|
116
|
+
try {
|
|
117
|
+
fs.unlinkSync(p);
|
|
118
|
+
} catch {
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
async function zoom(x1, y1, x2, y2) {
|
|
125
|
+
const regionScreenshotPath = `/tmp/screenshot_region-${Date.now()}.png`;
|
|
126
|
+
const left = Math.min(x1, x2);
|
|
127
|
+
const top = Math.min(y1, y2);
|
|
128
|
+
const width = Math.abs(x2 - x1);
|
|
129
|
+
const height = Math.abs(y2 - y1);
|
|
130
|
+
if (width <= 0 || height <= 0) {
|
|
131
|
+
throw new ScreenshotError(
|
|
132
|
+
"Invalid region dimensions",
|
|
133
|
+
new Error(`Width: ${width}, Height: ${height}`)
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
try {
|
|
137
|
+
await shell.execute(
|
|
138
|
+
`screencapture -x -R ${left},${top},${width},${height} ${regionScreenshotPath}`
|
|
139
|
+
);
|
|
140
|
+
const imageBuffer = fs.readFileSync(regionScreenshotPath);
|
|
141
|
+
return imageBuffer.toString("base64");
|
|
142
|
+
} catch (error) {
|
|
143
|
+
throw new ScreenshotError(
|
|
144
|
+
`Failed to capture region (${left},${top},${width}x${height})`,
|
|
145
|
+
error
|
|
146
|
+
);
|
|
147
|
+
} finally {
|
|
148
|
+
if (fs.existsSync(regionScreenshotPath)) {
|
|
149
|
+
try {
|
|
150
|
+
fs.unlinkSync(regionScreenshotPath);
|
|
151
|
+
} catch {
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// src/computer/client.ts
|
|
158
|
+
import Anthropic from "@anthropic-ai/sdk";
|
|
159
|
+
|
|
160
|
+
// src/computer/keyboard.ts
|
|
161
|
+
var KEY_MAP = {
|
|
162
|
+
enter: "return",
|
|
163
|
+
return: "return",
|
|
164
|
+
"\n": "return",
|
|
165
|
+
"\r": "return",
|
|
166
|
+
"num-enter": "num-enter",
|
|
167
|
+
escape: "esc",
|
|
168
|
+
esc: "esc",
|
|
169
|
+
tab: "tab",
|
|
170
|
+
backspace: "delete",
|
|
171
|
+
// macOS backspace
|
|
172
|
+
delete: "fwd-delete",
|
|
173
|
+
// macOS forward delete
|
|
174
|
+
space: "space",
|
|
175
|
+
up: "arrow-up",
|
|
176
|
+
down: "arrow-down",
|
|
177
|
+
left: "arrow-left",
|
|
178
|
+
right: "arrow-right",
|
|
179
|
+
home: "home",
|
|
180
|
+
end: "end",
|
|
181
|
+
pageup: "page-up",
|
|
182
|
+
pagedown: "page-down",
|
|
183
|
+
f1: "f1",
|
|
184
|
+
f2: "f2",
|
|
185
|
+
f3: "f3",
|
|
186
|
+
f4: "f4",
|
|
187
|
+
f5: "f5",
|
|
188
|
+
f6: "f6",
|
|
189
|
+
f7: "f7",
|
|
190
|
+
f8: "f8",
|
|
191
|
+
f9: "f9",
|
|
192
|
+
f10: "f10",
|
|
193
|
+
f11: "f11",
|
|
194
|
+
f12: "f12"
|
|
195
|
+
};
|
|
196
|
+
var MODIFIER_MAP = {
|
|
197
|
+
ctrl: "ctrl",
|
|
198
|
+
control: "ctrl",
|
|
199
|
+
alt: "alt",
|
|
200
|
+
option: "alt",
|
|
201
|
+
shift: "shift",
|
|
202
|
+
cmd: "cmd",
|
|
203
|
+
command: "cmd",
|
|
204
|
+
super: "cmd",
|
|
205
|
+
meta: "cmd",
|
|
206
|
+
win: "cmd"
|
|
207
|
+
};
|
|
208
|
+
async function typeText(text) {
|
|
209
|
+
if (!text) return;
|
|
210
|
+
const segments = text.split(/\r?\n/);
|
|
211
|
+
for (let i = 0; i < segments.length; i++) {
|
|
212
|
+
const segment = segments[i];
|
|
213
|
+
if (segment) {
|
|
214
|
+
const escapedText = segment.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/'/g, "\\'");
|
|
215
|
+
await shell.execute(`cliclick t:"${escapedText}"`);
|
|
216
|
+
}
|
|
217
|
+
if (i < segments.length - 1) {
|
|
218
|
+
await shell.execute("cliclick kp:return");
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
async function pressKey(key) {
|
|
223
|
+
if (!key) {
|
|
224
|
+
throw new Error("Key is required for pressKey action");
|
|
225
|
+
}
|
|
226
|
+
const keyLower = key.toLowerCase();
|
|
227
|
+
if (keyLower.includes("+")) {
|
|
228
|
+
await pressKeyCombination(keyLower);
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
const mappedKey = KEY_MAP[keyLower];
|
|
232
|
+
if (mappedKey) {
|
|
233
|
+
await shell.execute(`cliclick kp:${mappedKey}`);
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
if (MODIFIER_MAP[keyLower]) {
|
|
237
|
+
const mod = MODIFIER_MAP[keyLower];
|
|
238
|
+
await shell.execute(`cliclick kd:${mod} ku:${mod}`);
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
const escapedKey = key.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/'/g, "\\'");
|
|
242
|
+
await shell.execute(`cliclick t:"${escapedKey}"`);
|
|
243
|
+
}
|
|
244
|
+
async function pressKeyCombination(combo) {
|
|
245
|
+
const parts = combo.split("+").map((p) => p.trim());
|
|
246
|
+
const mainKey = parts.pop();
|
|
247
|
+
const mainKeyLower = mainKey.toLowerCase();
|
|
248
|
+
const modifiers = parts.map((m) => MODIFIER_MAP[m.toLowerCase()] || m.toLowerCase()).filter((m) => m);
|
|
249
|
+
const mappedKey = KEY_MAP[mainKeyLower];
|
|
250
|
+
const holdCmds = modifiers.map((m) => `kd:${m}`).join(" ");
|
|
251
|
+
const releaseCmds = modifiers.reverse().map((m) => `ku:${m}`).join(" ");
|
|
252
|
+
if (mappedKey) {
|
|
253
|
+
await shell.execute(`cliclick ${holdCmds} kp:${mappedKey} ${releaseCmds}`);
|
|
254
|
+
} else {
|
|
255
|
+
const escapedKey = mainKey.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/'/g, "\\'");
|
|
256
|
+
await shell.execute(
|
|
257
|
+
`cliclick ${holdCmds} t:"${escapedKey}" ${releaseCmds}`
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
async function holdKey(key, duration) {
|
|
262
|
+
if (!key) {
|
|
263
|
+
throw new Error("Key is required for holdKey action");
|
|
264
|
+
}
|
|
265
|
+
const keyLower = key.toLowerCase();
|
|
266
|
+
const cliclickKey = MODIFIER_MAP[keyLower] || KEY_MAP[keyLower] || keyLower;
|
|
267
|
+
const durationSec = Math.max(0.1, duration);
|
|
268
|
+
await shell.execute(
|
|
269
|
+
`cliclick kd:${cliclickKey} w:${Math.round(durationSec * 1e3)} ku:${cliclickKey}`
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// src/computer/mouse.ts
|
|
274
|
+
function getModifier(modifier) {
|
|
275
|
+
if (!modifier) return "";
|
|
276
|
+
switch (modifier.toLowerCase()) {
|
|
277
|
+
case "shift":
|
|
278
|
+
return "shift-";
|
|
279
|
+
case "ctrl":
|
|
280
|
+
return "ctrl-";
|
|
281
|
+
case "alt":
|
|
282
|
+
return "alt-";
|
|
283
|
+
case "super":
|
|
284
|
+
return "cmd-";
|
|
285
|
+
// 'super' usually maps to 'cmd' on macOS
|
|
286
|
+
default:
|
|
287
|
+
return "";
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
async function leftClick(x, y, modifier) {
|
|
291
|
+
const mod = getModifier(modifier);
|
|
292
|
+
await shell.execute(`cliclick ${mod}c:${x},${y}`);
|
|
293
|
+
}
|
|
294
|
+
async function mouseMove(x, y) {
|
|
295
|
+
await shell.execute(`cliclick m:${x},${y}`);
|
|
296
|
+
}
|
|
297
|
+
async function leftClickDrag(startX, startY, endX, endY) {
|
|
298
|
+
await shell.execute(`cliclick dd:${startX},${startY} du:${endX},${endY}`);
|
|
299
|
+
}
|
|
300
|
+
async function rightClick(x, y, modifier) {
|
|
301
|
+
const mod = getModifier(modifier);
|
|
302
|
+
await shell.execute(`cliclick ${mod}rc:${x},${y}`);
|
|
303
|
+
}
|
|
304
|
+
async function middleClick(x, y, modifier) {
|
|
305
|
+
console.warn(
|
|
306
|
+
"Middle click not directly supported by cliclick. Consider alternative implementation if needed."
|
|
307
|
+
);
|
|
308
|
+
await shell.execute(
|
|
309
|
+
`echo "Middle click at ${x},${y} with modifier ${modifier} requested but not fully supported by cliclick."`
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
async function doubleClick(x, y, modifier) {
|
|
313
|
+
const mod = getModifier(modifier);
|
|
314
|
+
await shell.execute(`cliclick ${mod}dc:${x},${y}`);
|
|
315
|
+
}
|
|
316
|
+
async function tripleClick(x, y, modifier) {
|
|
317
|
+
const mod = getModifier(modifier);
|
|
318
|
+
await shell.execute(`cliclick ${mod}tc:${x},${y}`);
|
|
319
|
+
}
|
|
320
|
+
async function leftMouseDown(x, y) {
|
|
321
|
+
await shell.execute(`cliclick dd:${x},${y}`);
|
|
322
|
+
}
|
|
323
|
+
async function leftMouseUp(x, y) {
|
|
324
|
+
await shell.execute(`cliclick du:${x},${y}`);
|
|
325
|
+
}
|
|
326
|
+
async function scroll(x, y, direction, amount, modifier) {
|
|
327
|
+
let scrollCommand = "";
|
|
328
|
+
const mod = getModifier(modifier);
|
|
329
|
+
await shell.execute(`cliclick m:${x},${y}`);
|
|
330
|
+
switch (direction) {
|
|
331
|
+
case "up":
|
|
332
|
+
scrollCommand = `${mod}sc:u${amount}`;
|
|
333
|
+
break;
|
|
334
|
+
case "down":
|
|
335
|
+
scrollCommand = `${mod}sc:d${amount}`;
|
|
336
|
+
break;
|
|
337
|
+
case "left":
|
|
338
|
+
scrollCommand = `${mod}sc:l${amount}`;
|
|
339
|
+
break;
|
|
340
|
+
case "right":
|
|
341
|
+
scrollCommand = `${mod}sc:r${amount}`;
|
|
342
|
+
break;
|
|
343
|
+
default:
|
|
344
|
+
console.warn(`Unsupported scroll direction: ${direction}`);
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
await shell.execute(`cliclick ${scrollCommand}`);
|
|
348
|
+
}
|
|
349
|
+
async function executeBatch(commands) {
|
|
350
|
+
const batchString = commands.join(" ");
|
|
351
|
+
await shell.execute(`cliclick ${batchString}`);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// src/computer/utils.ts
|
|
355
|
+
import { exec } from "child_process";
|
|
356
|
+
import { promisify } from "util";
|
|
357
|
+
var execAsync = promisify(exec);
|
|
358
|
+
async function wait(duration) {
|
|
359
|
+
await new Promise((resolve) => setTimeout(resolve, duration));
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// src/computer/accessibility.ts
|
|
363
|
+
async function getFocusedApp() {
|
|
364
|
+
try {
|
|
365
|
+
const script = `
|
|
366
|
+
tell application "System Events"
|
|
367
|
+
set frontApp to first application process whose frontmost is true
|
|
368
|
+
return name of frontApp
|
|
369
|
+
end tell
|
|
370
|
+
`;
|
|
371
|
+
const { stdout } = await shell.execute(`osascript -e '${script}'`);
|
|
372
|
+
return stdout.trim();
|
|
373
|
+
} catch (error) {
|
|
374
|
+
return "Unknown";
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
async function getFocusedWindowTitle() {
|
|
378
|
+
try {
|
|
379
|
+
const script = `
|
|
380
|
+
tell application "System Events"
|
|
381
|
+
set frontApp to first application process whose frontmost is true
|
|
382
|
+
tell frontApp
|
|
383
|
+
if (count of windows) > 0 then
|
|
384
|
+
return name of window 1
|
|
385
|
+
else
|
|
386
|
+
return ""
|
|
387
|
+
end if
|
|
388
|
+
end tell
|
|
389
|
+
end tell
|
|
390
|
+
`;
|
|
391
|
+
const { stdout } = await shell.execute(`osascript -e '${script}'`);
|
|
392
|
+
return stdout.trim();
|
|
393
|
+
} catch (error) {
|
|
394
|
+
return "";
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
async function findElementByLabel(label, appName) {
|
|
398
|
+
try {
|
|
399
|
+
const targetApp = appName || await getFocusedApp();
|
|
400
|
+
const script = `
|
|
401
|
+
tell application "System Events"
|
|
402
|
+
tell process "${targetApp}"
|
|
403
|
+
set targetElements to every UI element of window 1 whose name contains "${label}"
|
|
404
|
+
if (count of targetElements) > 0 then
|
|
405
|
+
set el to item 1 of targetElements
|
|
406
|
+
set elPos to position of el
|
|
407
|
+
set elSize to size of el
|
|
408
|
+
return (item 1 of elPos) & "," & (item 2 of elPos) & "," & (item 1 of elSize) & "," & (item 2 of elSize)
|
|
409
|
+
end if
|
|
410
|
+
|
|
411
|
+
-- Try deeper search in groups/scroll areas
|
|
412
|
+
set allGroups to every group of window 1
|
|
413
|
+
repeat with grp in allGroups
|
|
414
|
+
try
|
|
415
|
+
set targetElements to every UI element of grp whose name contains "${label}"
|
|
416
|
+
if (count of targetElements) > 0 then
|
|
417
|
+
set el to item 1 of targetElements
|
|
418
|
+
set elPos to position of el
|
|
419
|
+
set elSize to size of el
|
|
420
|
+
return (item 1 of elPos) & "," & (item 2 of elPos) & "," & (item 1 of elSize) & "," & (item 2 of elSize)
|
|
421
|
+
end if
|
|
422
|
+
end try
|
|
423
|
+
end repeat
|
|
424
|
+
|
|
425
|
+
return ""
|
|
426
|
+
end tell
|
|
427
|
+
end tell
|
|
428
|
+
`;
|
|
429
|
+
const { stdout } = await shell.execute(`osascript -e '${script}'`);
|
|
430
|
+
const result = stdout.trim();
|
|
431
|
+
if (!result) return null;
|
|
432
|
+
const [x, y, width, height] = result.split(",").map(Number);
|
|
433
|
+
return { x, y, width, height };
|
|
434
|
+
} catch (error) {
|
|
435
|
+
return null;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
async function findClickableByLabel(label) {
|
|
439
|
+
const element = await findElementByLabel(label);
|
|
440
|
+
if (!element) return null;
|
|
441
|
+
const centerX = Math.round(element.x + element.width / 2);
|
|
442
|
+
const centerY = Math.round(element.y + element.height / 2);
|
|
443
|
+
return [centerX, centerY];
|
|
444
|
+
}
|
|
445
|
+
async function clickElementByLabel(label, appName) {
|
|
446
|
+
try {
|
|
447
|
+
const targetApp = appName || await getFocusedApp();
|
|
448
|
+
const script = `
|
|
449
|
+
tell application "System Events"
|
|
450
|
+
tell process "${targetApp}"
|
|
451
|
+
set targetElements to every button of window 1 whose name contains "${label}"
|
|
452
|
+
if (count of targetElements) > 0 then
|
|
453
|
+
click item 1 of targetElements
|
|
454
|
+
return "clicked"
|
|
455
|
+
end if
|
|
456
|
+
|
|
457
|
+
-- Try menu items
|
|
458
|
+
set targetMenus to every menu item of every menu of menu bar 1 whose name contains "${label}"
|
|
459
|
+
if (count of targetMenus) > 0 then
|
|
460
|
+
click item 1 of targetMenus
|
|
461
|
+
return "clicked"
|
|
462
|
+
end if
|
|
463
|
+
|
|
464
|
+
return "not_found"
|
|
465
|
+
end tell
|
|
466
|
+
end tell
|
|
467
|
+
`;
|
|
468
|
+
const { stdout } = await shell.execute(`osascript -e '${script}'`);
|
|
469
|
+
return stdout.trim() === "clicked";
|
|
470
|
+
} catch (error) {
|
|
471
|
+
return false;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
async function getButtons(appName) {
|
|
475
|
+
try {
|
|
476
|
+
const targetApp = appName || await getFocusedApp();
|
|
477
|
+
const script = `
|
|
478
|
+
set buttonNames to {}
|
|
479
|
+
tell application "System Events"
|
|
480
|
+
tell process "${targetApp}"
|
|
481
|
+
if (count of windows) > 0 then
|
|
482
|
+
set allButtons to every button of window 1
|
|
483
|
+
repeat with btn in allButtons
|
|
484
|
+
try
|
|
485
|
+
set end of buttonNames to name of btn
|
|
486
|
+
end try
|
|
487
|
+
end repeat
|
|
488
|
+
end if
|
|
489
|
+
end tell
|
|
490
|
+
end tell
|
|
491
|
+
return buttonNames as text
|
|
492
|
+
`;
|
|
493
|
+
const { stdout } = await shell.execute(`osascript -e '${script}'`);
|
|
494
|
+
return stdout.trim().split(", ").filter((b) => b);
|
|
495
|
+
} catch (error) {
|
|
496
|
+
return [];
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
async function getTextFields(appName) {
|
|
500
|
+
try {
|
|
501
|
+
const targetApp = appName || await getFocusedApp();
|
|
502
|
+
const script = `
|
|
503
|
+
set fieldNames to {}
|
|
504
|
+
tell application "System Events"
|
|
505
|
+
tell process "${targetApp}"
|
|
506
|
+
if (count of windows) > 0 then
|
|
507
|
+
set allFields to every text field of window 1
|
|
508
|
+
repeat with fld in allFields
|
|
509
|
+
try
|
|
510
|
+
set end of fieldNames to description of fld
|
|
511
|
+
end try
|
|
512
|
+
end repeat
|
|
513
|
+
end if
|
|
514
|
+
end tell
|
|
515
|
+
end tell
|
|
516
|
+
return fieldNames as text
|
|
517
|
+
`;
|
|
518
|
+
const { stdout } = await shell.execute(`osascript -e '${script}'`);
|
|
519
|
+
return stdout.trim().split(", ").filter((f) => f);
|
|
520
|
+
} catch (error) {
|
|
521
|
+
return [];
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
async function activateApp(appName) {
|
|
525
|
+
try {
|
|
526
|
+
const script = `
|
|
527
|
+
tell application "${appName}"
|
|
528
|
+
activate
|
|
529
|
+
end tell
|
|
530
|
+
return "ok"
|
|
531
|
+
`;
|
|
532
|
+
const { stdout } = await shell.execute(`osascript -e '${script}'`);
|
|
533
|
+
return stdout.trim() === "ok";
|
|
534
|
+
} catch (error) {
|
|
535
|
+
return false;
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
async function getUIContext() {
|
|
539
|
+
const [app, windowTitle, buttons, textFields] = await Promise.all([
|
|
540
|
+
getFocusedApp(),
|
|
541
|
+
getFocusedWindowTitle(),
|
|
542
|
+
getButtons(),
|
|
543
|
+
getTextFields()
|
|
544
|
+
]);
|
|
545
|
+
const lines = [`Focused App: ${app}`, `Window: ${windowTitle || "(none)"}`];
|
|
546
|
+
if (buttons.length > 0) {
|
|
547
|
+
lines.push(
|
|
548
|
+
`Buttons: ${buttons.slice(0, 10).join(", ")}${buttons.length > 10 ? "..." : ""}`
|
|
549
|
+
);
|
|
550
|
+
}
|
|
551
|
+
if (textFields.length > 0) {
|
|
552
|
+
lines.push(
|
|
553
|
+
`Text Fields: ${textFields.slice(0, 5).join(", ")}${textFields.length > 5 ? "..." : ""}`
|
|
554
|
+
);
|
|
555
|
+
}
|
|
556
|
+
return lines.join("\n");
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
// src/computer/index.ts
|
|
560
|
+
var macComputer = {
|
|
561
|
+
takeScreenshot,
|
|
562
|
+
leftClick,
|
|
563
|
+
typeText,
|
|
564
|
+
pressKey,
|
|
565
|
+
mouseMove,
|
|
566
|
+
scroll,
|
|
567
|
+
leftClickDrag,
|
|
568
|
+
rightClick,
|
|
569
|
+
middleClick,
|
|
570
|
+
doubleClick,
|
|
571
|
+
tripleClick,
|
|
572
|
+
leftMouseDown,
|
|
573
|
+
leftMouseUp,
|
|
574
|
+
holdKey,
|
|
575
|
+
wait,
|
|
576
|
+
zoom,
|
|
577
|
+
getDisplayDimensions,
|
|
578
|
+
executeBatch
|
|
579
|
+
};
|
|
580
|
+
var unimplementedComputer = {
|
|
581
|
+
takeScreenshot: async () => {
|
|
582
|
+
throw new Error(
|
|
583
|
+
"Computer use not implemented for this platform. Currently macOS only."
|
|
584
|
+
);
|
|
585
|
+
},
|
|
586
|
+
leftClick: async () => {
|
|
587
|
+
throw new Error("Computer use not implemented for this platform.");
|
|
588
|
+
},
|
|
589
|
+
typeText: async () => {
|
|
590
|
+
throw new Error("Computer use not implemented for this platform.");
|
|
591
|
+
},
|
|
592
|
+
pressKey: async () => {
|
|
593
|
+
throw new Error("Computer use not implemented for this platform.");
|
|
594
|
+
},
|
|
595
|
+
mouseMove: async () => {
|
|
596
|
+
throw new Error("Computer use not implemented for this platform.");
|
|
597
|
+
},
|
|
598
|
+
scroll: async () => {
|
|
599
|
+
throw new Error("Computer use not implemented for this platform.");
|
|
600
|
+
},
|
|
601
|
+
leftClickDrag: async () => {
|
|
602
|
+
throw new Error("Computer use not implemented for this platform.");
|
|
603
|
+
},
|
|
604
|
+
rightClick: async () => {
|
|
605
|
+
throw new Error("Computer use not implemented for this platform.");
|
|
606
|
+
},
|
|
607
|
+
middleClick: async () => {
|
|
608
|
+
throw new Error("Computer use not implemented for this platform.");
|
|
609
|
+
},
|
|
610
|
+
doubleClick: async () => {
|
|
611
|
+
throw new Error("Computer use not implemented for this platform.");
|
|
612
|
+
},
|
|
613
|
+
tripleClick: async () => {
|
|
614
|
+
throw new Error("Computer use not implemented for this platform.");
|
|
615
|
+
},
|
|
616
|
+
leftMouseDown: async () => {
|
|
617
|
+
throw new Error("Computer use not implemented for this platform.");
|
|
618
|
+
},
|
|
619
|
+
leftMouseUp: async () => {
|
|
620
|
+
throw new Error("Computer use not implemented for this platform.");
|
|
621
|
+
},
|
|
622
|
+
holdKey: async () => {
|
|
623
|
+
throw new Error("Computer use not implemented for this platform.");
|
|
624
|
+
},
|
|
625
|
+
wait: async () => {
|
|
626
|
+
throw new Error("Computer use not implemented for this platform.");
|
|
627
|
+
},
|
|
628
|
+
zoom: async () => {
|
|
629
|
+
throw new Error("Computer use not implemented for this platform.");
|
|
630
|
+
},
|
|
631
|
+
getDisplayDimensions: async () => {
|
|
632
|
+
throw new Error("Computer use not implemented for this platform.");
|
|
633
|
+
},
|
|
634
|
+
executeBatch: async () => {
|
|
635
|
+
throw new Error("Computer use not implemented for this platform.");
|
|
636
|
+
}
|
|
637
|
+
};
|
|
638
|
+
var computer = process.platform === "darwin" ? macComputer : unimplementedComputer;
|
|
639
|
+
function isComputerUseAvailable() {
|
|
640
|
+
return process.platform === "darwin";
|
|
641
|
+
}
|
|
642
|
+
async function checkDependencies() {
|
|
643
|
+
if (process.platform !== "darwin") {
|
|
644
|
+
return { available: false, missing: ["macOS required"] };
|
|
645
|
+
}
|
|
646
|
+
const { shell: shell2 } = await import("./shell-FM34624T.js");
|
|
647
|
+
const missing = [];
|
|
648
|
+
try {
|
|
649
|
+
await shell2.execute("which cliclick");
|
|
650
|
+
} catch {
|
|
651
|
+
missing.push("cliclick (install with: brew install cliclick)");
|
|
652
|
+
}
|
|
653
|
+
return {
|
|
654
|
+
available: missing.length === 0,
|
|
655
|
+
missing
|
|
656
|
+
};
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
// src/computer/client.ts
|
|
660
|
+
function getToolConfig(model) {
|
|
661
|
+
if (model.includes("opus-4-5") || model.includes("opus-4.5")) {
|
|
662
|
+
return {
|
|
663
|
+
toolVersion: "computer_20251124",
|
|
664
|
+
betaFlag: "computer-use-2025-11-24"
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
return {
|
|
668
|
+
toolVersion: "computer_20250124",
|
|
669
|
+
betaFlag: "computer-use-2025-01-24"
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
export {
|
|
674
|
+
getDisplayDimensions,
|
|
675
|
+
calculateScaleForAPI,
|
|
676
|
+
takeScreenshotForAPI,
|
|
677
|
+
getToolConfig,
|
|
678
|
+
getFocusedApp,
|
|
679
|
+
findClickableByLabel,
|
|
680
|
+
clickElementByLabel,
|
|
681
|
+
getButtons,
|
|
682
|
+
activateApp,
|
|
683
|
+
getUIContext,
|
|
684
|
+
computer,
|
|
685
|
+
isComputerUseAvailable,
|
|
686
|
+
checkDependencies
|
|
687
|
+
};
|