simen-keyboard-listener 1.1.8 → 1.1.10
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/dist/index.d.mts +518 -1
- package/dist/index.d.ts +518 -1
- package/dist/index.js +1400 -11
- package/dist/index.mjs +1371 -8
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -32,21 +32,1384 @@ var index_exports = {};
|
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
checkKeyboardPermission: () => checkKeyboardPermission,
|
|
34
34
|
createGlobalKeyboardListener: () => createGlobalKeyboardListener,
|
|
35
|
+
escapeForAppleScript: () => escapeForAppleScript,
|
|
36
|
+
executeAndParse: () => executeAndParse,
|
|
37
|
+
executeAppleScript: () => executeAppleScript,
|
|
38
|
+
executeAppleScriptLines: () => executeAppleScriptLines,
|
|
39
|
+
executeMultilineAndParse: () => executeMultilineAndParse,
|
|
40
|
+
getAgentContext: () => getAgentContext,
|
|
41
|
+
getClipboardContent: () => getClipboardContent,
|
|
42
|
+
getClipboardText: () => getClipboardText,
|
|
35
43
|
getContextJSON: () => getContextJSON,
|
|
44
|
+
getDesktopItems: () => getDesktopItems,
|
|
45
|
+
getDesktopPath: () => getDesktopPath,
|
|
46
|
+
getFileMetadata: () => getFileMetadata,
|
|
47
|
+
getFilesMetadata: () => getFilesMetadata,
|
|
48
|
+
getFinderContext: () => getFinderContext,
|
|
49
|
+
getFinderCurrentFolder: () => getFinderCurrentFolder,
|
|
50
|
+
getFinderSelection: () => getFinderSelection,
|
|
51
|
+
getFinderWindows: () => getFinderWindows,
|
|
36
52
|
getFocusedInputSelectedText: () => getFocusedInputSelectedText,
|
|
37
53
|
getFocusedInputValue: () => getFocusedInputValue,
|
|
54
|
+
getFrontmostApp: () => getFrontmostApp,
|
|
55
|
+
getFrontmostFromRunning: () => getFrontmostFromRunning,
|
|
38
56
|
getGlobalKeyboardListener: () => getGlobalKeyboardListener,
|
|
57
|
+
getRecentDocuments: () => getRecentDocuments,
|
|
58
|
+
getRecentFiles: () => getRecentFiles,
|
|
59
|
+
getRunningApps: () => getRunningApps,
|
|
39
60
|
getSelectedTextSmart: () => getSelectedTextSmart,
|
|
61
|
+
getSystemContext: () => getSystemContext,
|
|
62
|
+
isAppRunning: () => isAppRunning,
|
|
63
|
+
isOsascriptAvailable: () => isOsascriptAvailable,
|
|
64
|
+
readFileContent: () => readFileContent,
|
|
65
|
+
readMultipleFiles: () => readMultipleFiles,
|
|
40
66
|
setBlockSystemHotkeys: () => setBlockSystemHotkeys
|
|
41
67
|
});
|
|
42
68
|
module.exports = __toCommonJS(index_exports);
|
|
43
69
|
var path = __toESM(require("path"));
|
|
44
70
|
var fs = __toESM(require("fs"));
|
|
45
|
-
var
|
|
71
|
+
var import_node_child_process2 = require("child_process");
|
|
46
72
|
var import_node_module = require("module");
|
|
47
73
|
var import_url = require("url");
|
|
48
|
-
|
|
74
|
+
|
|
75
|
+
// src/osascript/executor.ts
|
|
76
|
+
var import_node_child_process = require("child_process");
|
|
77
|
+
var import_node_util = require("util");
|
|
78
|
+
var execFileAsync = (0, import_node_util.promisify)(import_node_child_process.execFile);
|
|
49
79
|
var IS_MACOS = process.platform === "darwin";
|
|
80
|
+
var OSASCRIPT_PATH = "/usr/bin/osascript";
|
|
81
|
+
var DEFAULT_TIMEOUT = 3e4;
|
|
82
|
+
function isOsascriptAvailable() {
|
|
83
|
+
return IS_MACOS;
|
|
84
|
+
}
|
|
85
|
+
async function executeAppleScript(script, options) {
|
|
86
|
+
if (!IS_MACOS) {
|
|
87
|
+
return {
|
|
88
|
+
success: false,
|
|
89
|
+
error: "osascript is only available on macOS"
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
const timeout = options?.timeout ?? DEFAULT_TIMEOUT;
|
|
93
|
+
const startTime = Date.now();
|
|
94
|
+
try {
|
|
95
|
+
const { stdout, stderr } = await execFileAsync(
|
|
96
|
+
OSASCRIPT_PATH,
|
|
97
|
+
["-e", script],
|
|
98
|
+
{ timeout }
|
|
99
|
+
);
|
|
100
|
+
const executionTime = Date.now() - startTime;
|
|
101
|
+
if (stderr && stderr.trim()) {
|
|
102
|
+
return {
|
|
103
|
+
success: false,
|
|
104
|
+
error: stderr.trim(),
|
|
105
|
+
executionTime
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
success: true,
|
|
110
|
+
data: stdout.trim(),
|
|
111
|
+
executionTime
|
|
112
|
+
};
|
|
113
|
+
} catch (error) {
|
|
114
|
+
const executionTime = Date.now() - startTime;
|
|
115
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
116
|
+
return {
|
|
117
|
+
success: false,
|
|
118
|
+
error: errorMessage,
|
|
119
|
+
executionTime
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
async function executeAppleScriptLines(lines, options) {
|
|
124
|
+
if (!IS_MACOS) {
|
|
125
|
+
return {
|
|
126
|
+
success: false,
|
|
127
|
+
error: "osascript is only available on macOS"
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
const timeout = options?.timeout ?? DEFAULT_TIMEOUT;
|
|
131
|
+
const startTime = Date.now();
|
|
132
|
+
const args = lines.flatMap((line) => ["-e", line]);
|
|
133
|
+
try {
|
|
134
|
+
const { stdout, stderr } = await execFileAsync(
|
|
135
|
+
OSASCRIPT_PATH,
|
|
136
|
+
args,
|
|
137
|
+
{ timeout }
|
|
138
|
+
);
|
|
139
|
+
const executionTime = Date.now() - startTime;
|
|
140
|
+
if (stderr && stderr.trim()) {
|
|
141
|
+
return {
|
|
142
|
+
success: false,
|
|
143
|
+
error: stderr.trim(),
|
|
144
|
+
executionTime
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
success: true,
|
|
149
|
+
data: stdout.trim(),
|
|
150
|
+
executionTime
|
|
151
|
+
};
|
|
152
|
+
} catch (error) {
|
|
153
|
+
const executionTime = Date.now() - startTime;
|
|
154
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
155
|
+
return {
|
|
156
|
+
success: false,
|
|
157
|
+
error: errorMessage,
|
|
158
|
+
executionTime
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
async function executeAndParse(script, parser, options) {
|
|
163
|
+
const result = await executeAppleScript(script, options);
|
|
164
|
+
if (!result.success) {
|
|
165
|
+
return {
|
|
166
|
+
success: false,
|
|
167
|
+
error: result.error,
|
|
168
|
+
executionTime: result.executionTime
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
try {
|
|
172
|
+
const parsed = parser(result.data ?? "");
|
|
173
|
+
return {
|
|
174
|
+
success: true,
|
|
175
|
+
data: parsed,
|
|
176
|
+
executionTime: result.executionTime
|
|
177
|
+
};
|
|
178
|
+
} catch (parseError) {
|
|
179
|
+
const errorMessage = parseError instanceof Error ? parseError.message : String(parseError);
|
|
180
|
+
return {
|
|
181
|
+
success: false,
|
|
182
|
+
error: `Failed to parse output: ${errorMessage}`,
|
|
183
|
+
executionTime: result.executionTime
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
async function executeMultilineAndParse(lines, parser, options) {
|
|
188
|
+
const result = await executeAppleScriptLines(lines, options);
|
|
189
|
+
if (!result.success) {
|
|
190
|
+
return {
|
|
191
|
+
success: false,
|
|
192
|
+
error: result.error,
|
|
193
|
+
executionTime: result.executionTime
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
try {
|
|
197
|
+
const parsed = parser(result.data ?? "");
|
|
198
|
+
return {
|
|
199
|
+
success: true,
|
|
200
|
+
data: parsed,
|
|
201
|
+
executionTime: result.executionTime
|
|
202
|
+
};
|
|
203
|
+
} catch (parseError) {
|
|
204
|
+
const errorMessage = parseError instanceof Error ? parseError.message : String(parseError);
|
|
205
|
+
return {
|
|
206
|
+
success: false,
|
|
207
|
+
error: `Failed to parse output: ${errorMessage}`,
|
|
208
|
+
executionTime: result.executionTime
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
function escapeForAppleScript(str) {
|
|
213
|
+
return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// src/osascript/scripts/batchContext.ts
|
|
217
|
+
var SEC = "\xA7\xA7\xA7";
|
|
218
|
+
var FLD = "|||";
|
|
219
|
+
var ITM = ":::";
|
|
220
|
+
var SCRIPT_BASIC = `
|
|
221
|
+
set d to "${FLD}"
|
|
222
|
+
set s to "${SEC}"
|
|
223
|
+
set i to "${ITM}"
|
|
224
|
+
|
|
225
|
+
tell application "System Events"
|
|
226
|
+
set fp to first application process whose frontmost is true
|
|
227
|
+
set appName to displayed name of fp
|
|
228
|
+
set sec0 to appName & d & bundle identifier of fp & d
|
|
229
|
+
try
|
|
230
|
+
set sec0 to sec0 & POSIX path of (file of fp as alias)
|
|
231
|
+
end try
|
|
232
|
+
set finderRunning to (exists process "Finder")
|
|
233
|
+
end tell
|
|
234
|
+
|
|
235
|
+
set sec1 to ""
|
|
236
|
+
set sec2 to ""
|
|
237
|
+
set sec3 to ""
|
|
238
|
+
set sec4 to do shell script "echo $HOME/Desktop/"
|
|
239
|
+
|
|
240
|
+
if not finderRunning then
|
|
241
|
+
-- Skip Finder operations if not running
|
|
242
|
+
else
|
|
243
|
+
-- Get Finder selection (must be in separate tell block to avoid scope issues)
|
|
244
|
+
try
|
|
245
|
+
tell application "Finder"
|
|
246
|
+
set sel to selection
|
|
247
|
+
set sc to count of sel
|
|
248
|
+
if sc > 0 then
|
|
249
|
+
set L to {}
|
|
250
|
+
repeat with j from 1 to sc
|
|
251
|
+
if j > 50 then exit repeat
|
|
252
|
+
set f to item j of sel
|
|
253
|
+
set t to "0"
|
|
254
|
+
if class of f as string contains "folder" then set t to "1"
|
|
255
|
+
set end of L to name of f & d & POSIX path of (f as alias) & d & t
|
|
256
|
+
end repeat
|
|
257
|
+
set {tid, AppleScript's text item delimiters} to {AppleScript's text item delimiters, i}
|
|
258
|
+
set sec1 to L as string
|
|
259
|
+
set AppleScript's text item delimiters to tid
|
|
260
|
+
end if
|
|
261
|
+
end tell
|
|
262
|
+
end try
|
|
263
|
+
|
|
264
|
+
-- Get Finder windows (including special views like Recents)
|
|
265
|
+
try
|
|
266
|
+
tell application "Finder"
|
|
267
|
+
set wc to count of Finder windows
|
|
268
|
+
if wc > 0 then
|
|
269
|
+
-- Try to get current folder path (may fail for special views)
|
|
270
|
+
try
|
|
271
|
+
set sec2 to POSIX path of (target of front Finder window as alias)
|
|
272
|
+
on error
|
|
273
|
+
-- Special view (Recents, Search, etc.) - use window name as identifier
|
|
274
|
+
set sec2 to "special:" & (name of front Finder window)
|
|
275
|
+
end try
|
|
276
|
+
set L to {}
|
|
277
|
+
repeat with idx from 1 to wc
|
|
278
|
+
set w to Finder window idx
|
|
279
|
+
set wName to name of w
|
|
280
|
+
set wPath to ""
|
|
281
|
+
try
|
|
282
|
+
set wPath to POSIX path of (target of w as alias)
|
|
283
|
+
on error
|
|
284
|
+
-- Special view - mark with special: prefix
|
|
285
|
+
set wPath to "special:" & wName
|
|
286
|
+
end try
|
|
287
|
+
set end of L to wName & d & wPath & d & (idx as string)
|
|
288
|
+
end repeat
|
|
289
|
+
set {tid, AppleScript's text item delimiters} to {AppleScript's text item delimiters, i}
|
|
290
|
+
set sec3 to L as string
|
|
291
|
+
set AppleScript's text item delimiters to tid
|
|
292
|
+
end if
|
|
293
|
+
end tell
|
|
294
|
+
end try
|
|
295
|
+
end if
|
|
296
|
+
|
|
297
|
+
set sec5 to ""
|
|
298
|
+
try
|
|
299
|
+
set c to the clipboard as text
|
|
300
|
+
if (length of c) > 2000 then set c to text 1 thru 2000 of c
|
|
301
|
+
set sec5 to c
|
|
302
|
+
end try
|
|
303
|
+
|
|
304
|
+
set sec6 to ""
|
|
305
|
+
try
|
|
306
|
+
set cf to the clipboard as alias list
|
|
307
|
+
set L to {}
|
|
308
|
+
repeat with f in cf
|
|
309
|
+
set end of L to POSIX path of f
|
|
310
|
+
end repeat
|
|
311
|
+
set {tid, AppleScript's text item delimiters} to {AppleScript's text item delimiters, i}
|
|
312
|
+
set sec6 to L as string
|
|
313
|
+
set AppleScript's text item delimiters to tid
|
|
314
|
+
end try
|
|
315
|
+
|
|
316
|
+
set sec7 to "0"
|
|
317
|
+
try
|
|
318
|
+
set imgData to the clipboard as \xABclass PNGf\xBB
|
|
319
|
+
set sec7 to "1"
|
|
320
|
+
on error
|
|
321
|
+
try
|
|
322
|
+
set imgData to the clipboard as TIFF picture
|
|
323
|
+
set sec7 to "1"
|
|
324
|
+
end try
|
|
325
|
+
end try
|
|
326
|
+
|
|
327
|
+
return sec0 & s & sec1 & s & sec2 & s & sec3 & s & sec4 & s & sec5 & s & sec6 & s & sec7
|
|
328
|
+
`;
|
|
329
|
+
var SCRIPT_WITH_METADATA = `
|
|
330
|
+
set d to "${FLD}"
|
|
331
|
+
set s to "${SEC}"
|
|
332
|
+
set i to "${ITM}"
|
|
333
|
+
|
|
334
|
+
tell application "System Events"
|
|
335
|
+
set fp to first application process whose frontmost is true
|
|
336
|
+
set appName to displayed name of fp
|
|
337
|
+
set sec0 to appName & d & bundle identifier of fp & d
|
|
338
|
+
try
|
|
339
|
+
set sec0 to sec0 & POSIX path of (file of fp as alias)
|
|
340
|
+
end try
|
|
341
|
+
set finderRunning to (exists process "Finder")
|
|
342
|
+
end tell
|
|
343
|
+
|
|
344
|
+
set sec1 to ""
|
|
345
|
+
set sec2 to ""
|
|
346
|
+
set sec3 to ""
|
|
347
|
+
set sec4 to do shell script "echo $HOME/Desktop/"
|
|
348
|
+
|
|
349
|
+
if not finderRunning then
|
|
350
|
+
-- Skip Finder operations if not running
|
|
351
|
+
else
|
|
352
|
+
-- Get Finder selection with metadata (must be in separate tell block)
|
|
353
|
+
try
|
|
354
|
+
tell application "Finder"
|
|
355
|
+
set sel to selection
|
|
356
|
+
set sc to count of sel
|
|
357
|
+
if sc > 0 then
|
|
358
|
+
set L to {}
|
|
359
|
+
repeat with j from 1 to sc
|
|
360
|
+
if j > 50 then exit repeat
|
|
361
|
+
set f to item j of sel
|
|
362
|
+
set t to "0"
|
|
363
|
+
if class of f as string contains "folder" then set t to "1"
|
|
364
|
+
set fSize to "0"
|
|
365
|
+
set fMod to ""
|
|
366
|
+
try
|
|
367
|
+
set fSize to size of f as string
|
|
368
|
+
end try
|
|
369
|
+
try
|
|
370
|
+
set fMod to (modification date of f) as string
|
|
371
|
+
end try
|
|
372
|
+
set end of L to name of f & d & POSIX path of (f as alias) & d & t & d & fSize & d & fMod
|
|
373
|
+
end repeat
|
|
374
|
+
set {tid, AppleScript's text item delimiters} to {AppleScript's text item delimiters, i}
|
|
375
|
+
set sec1 to L as string
|
|
376
|
+
set AppleScript's text item delimiters to tid
|
|
377
|
+
end if
|
|
378
|
+
end tell
|
|
379
|
+
end try
|
|
380
|
+
|
|
381
|
+
-- Get Finder windows (including special views like Recents)
|
|
382
|
+
try
|
|
383
|
+
tell application "Finder"
|
|
384
|
+
set wc to count of Finder windows
|
|
385
|
+
if wc > 0 then
|
|
386
|
+
-- Try to get current folder path (may fail for special views)
|
|
387
|
+
try
|
|
388
|
+
set sec2 to POSIX path of (target of front Finder window as alias)
|
|
389
|
+
on error
|
|
390
|
+
-- Special view (Recents, Search, etc.) - use window name as identifier
|
|
391
|
+
set sec2 to "special:" & (name of front Finder window)
|
|
392
|
+
end try
|
|
393
|
+
set L to {}
|
|
394
|
+
repeat with idx from 1 to wc
|
|
395
|
+
set w to Finder window idx
|
|
396
|
+
set wName to name of w
|
|
397
|
+
set wPath to ""
|
|
398
|
+
try
|
|
399
|
+
set wPath to POSIX path of (target of w as alias)
|
|
400
|
+
on error
|
|
401
|
+
-- Special view - mark with special: prefix
|
|
402
|
+
set wPath to "special:" & wName
|
|
403
|
+
end try
|
|
404
|
+
set end of L to wName & d & wPath & d & (idx as string)
|
|
405
|
+
end repeat
|
|
406
|
+
set {tid, AppleScript's text item delimiters} to {AppleScript's text item delimiters, i}
|
|
407
|
+
set sec3 to L as string
|
|
408
|
+
set AppleScript's text item delimiters to tid
|
|
409
|
+
end if
|
|
410
|
+
end tell
|
|
411
|
+
end try
|
|
412
|
+
end if
|
|
413
|
+
|
|
414
|
+
set sec5 to ""
|
|
415
|
+
try
|
|
416
|
+
set c to the clipboard as text
|
|
417
|
+
if (length of c) > 2000 then set c to text 1 thru 2000 of c
|
|
418
|
+
set sec5 to c
|
|
419
|
+
end try
|
|
420
|
+
|
|
421
|
+
set sec6 to ""
|
|
422
|
+
try
|
|
423
|
+
set cf to the clipboard as alias list
|
|
424
|
+
set L to {}
|
|
425
|
+
repeat with f in cf
|
|
426
|
+
set end of L to POSIX path of f
|
|
427
|
+
end repeat
|
|
428
|
+
set {tid, AppleScript's text item delimiters} to {AppleScript's text item delimiters, i}
|
|
429
|
+
set sec6 to L as string
|
|
430
|
+
set AppleScript's text item delimiters to tid
|
|
431
|
+
end try
|
|
432
|
+
|
|
433
|
+
set sec7 to "0"
|
|
434
|
+
try
|
|
435
|
+
set imgData to the clipboard as \xABclass PNGf\xBB
|
|
436
|
+
set sec7 to "1"
|
|
437
|
+
on error
|
|
438
|
+
try
|
|
439
|
+
set imgData to the clipboard as TIFF picture
|
|
440
|
+
set sec7 to "1"
|
|
441
|
+
end try
|
|
442
|
+
end try
|
|
443
|
+
|
|
444
|
+
return sec0 & s & sec1 & s & sec2 & s & sec3 & s & sec4 & s & sec5 & s & sec6 & s & sec7
|
|
445
|
+
`;
|
|
446
|
+
function parseBasic(out) {
|
|
447
|
+
const s = out.split(SEC);
|
|
448
|
+
const app = (s[0] ?? "").split(FLD);
|
|
449
|
+
const items = [];
|
|
450
|
+
const paths = [];
|
|
451
|
+
if (s[1]?.trim()) {
|
|
452
|
+
for (const item of s[1].split(ITM)) {
|
|
453
|
+
const p = item.split(FLD);
|
|
454
|
+
if (p.length >= 3) {
|
|
455
|
+
items.push({ name: p[0], path: p[1], isFolder: p[2] === "1" });
|
|
456
|
+
paths.push(p[1]);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
const windows = [];
|
|
461
|
+
if (s[3]?.trim()) {
|
|
462
|
+
for (const win of s[3].split(ITM)) {
|
|
463
|
+
const p = win.split(FLD);
|
|
464
|
+
if (p.length >= 3) {
|
|
465
|
+
const isSpecial = p[1].startsWith("special:");
|
|
466
|
+
windows.push({
|
|
467
|
+
name: p[0],
|
|
468
|
+
path: isSpecial ? null : p[1],
|
|
469
|
+
index: parseInt(p[2], 10) || 0,
|
|
470
|
+
isSpecialView: isSpecial
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
const currentFolder = s[2]?.trim() || null;
|
|
476
|
+
const finderCurrentFolder = currentFolder?.startsWith("special:") ? null : currentFolder;
|
|
477
|
+
const clipPaths = s[6]?.trim() ? s[6].split(ITM).filter((p) => p.trim()) : [];
|
|
478
|
+
const hasImage = s[7]?.trim() === "1";
|
|
479
|
+
return {
|
|
480
|
+
frontmostApp: {
|
|
481
|
+
name: app[0] ?? "",
|
|
482
|
+
bundleId: app[1] ?? "",
|
|
483
|
+
isFinder: app[1] === "com.apple.finder",
|
|
484
|
+
path: app[2] ?? ""
|
|
485
|
+
},
|
|
486
|
+
finderSelection: { count: items.length, items, paths },
|
|
487
|
+
finderCurrentFolder,
|
|
488
|
+
finderWindows: windows,
|
|
489
|
+
desktopPath: s[4]?.trim() || "",
|
|
490
|
+
clipboard: {
|
|
491
|
+
text: s[5]?.trim() || null,
|
|
492
|
+
hasFiles: clipPaths.length > 0,
|
|
493
|
+
filePaths: clipPaths,
|
|
494
|
+
hasImage
|
|
495
|
+
},
|
|
496
|
+
timestamp: Date.now()
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
function parseWithMetadata(out) {
|
|
500
|
+
const s = out.split(SEC);
|
|
501
|
+
const app = (s[0] ?? "").split(FLD);
|
|
502
|
+
const items = [];
|
|
503
|
+
const paths = [];
|
|
504
|
+
if (s[1]?.trim()) {
|
|
505
|
+
for (const item of s[1].split(ITM)) {
|
|
506
|
+
const p = item.split(FLD);
|
|
507
|
+
if (p.length >= 3) {
|
|
508
|
+
const selectedItem = {
|
|
509
|
+
name: p[0],
|
|
510
|
+
path: p[1],
|
|
511
|
+
isFolder: p[2] === "1"
|
|
512
|
+
};
|
|
513
|
+
if (p.length >= 4 && p[3]) {
|
|
514
|
+
selectedItem.size = parseInt(p[3], 10) || 0;
|
|
515
|
+
}
|
|
516
|
+
if (p.length >= 5 && p[4]) {
|
|
517
|
+
selectedItem.modifiedAt = p[4];
|
|
518
|
+
}
|
|
519
|
+
items.push(selectedItem);
|
|
520
|
+
paths.push(p[1]);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
const windows = [];
|
|
525
|
+
if (s[3]?.trim()) {
|
|
526
|
+
for (const win of s[3].split(ITM)) {
|
|
527
|
+
const p = win.split(FLD);
|
|
528
|
+
if (p.length >= 3) {
|
|
529
|
+
const isSpecial = p[1].startsWith("special:");
|
|
530
|
+
windows.push({
|
|
531
|
+
name: p[0],
|
|
532
|
+
path: isSpecial ? null : p[1],
|
|
533
|
+
index: parseInt(p[2], 10) || 0,
|
|
534
|
+
isSpecialView: isSpecial
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
const currentFolder = s[2]?.trim() || null;
|
|
540
|
+
const finderCurrentFolder = currentFolder?.startsWith("special:") ? null : currentFolder;
|
|
541
|
+
const clipPaths = s[6]?.trim() ? s[6].split(ITM).filter((p) => p.trim()) : [];
|
|
542
|
+
const hasImage = s[7]?.trim() === "1";
|
|
543
|
+
return {
|
|
544
|
+
frontmostApp: {
|
|
545
|
+
name: app[0] ?? "",
|
|
546
|
+
bundleId: app[1] ?? "",
|
|
547
|
+
isFinder: app[1] === "com.apple.finder",
|
|
548
|
+
path: app[2] ?? ""
|
|
549
|
+
},
|
|
550
|
+
finderSelection: { count: items.length, items, paths },
|
|
551
|
+
finderCurrentFolder,
|
|
552
|
+
finderWindows: windows,
|
|
553
|
+
desktopPath: s[4]?.trim() || "",
|
|
554
|
+
clipboard: {
|
|
555
|
+
text: s[5]?.trim() || null,
|
|
556
|
+
hasFiles: clipPaths.length > 0,
|
|
557
|
+
filePaths: clipPaths,
|
|
558
|
+
hasImage
|
|
559
|
+
},
|
|
560
|
+
timestamp: Date.now()
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
async function getAgentContext(opts) {
|
|
564
|
+
if (!isOsascriptAvailable()) return null;
|
|
565
|
+
const script = opts?.includeMetadata ? SCRIPT_WITH_METADATA : SCRIPT_BASIC;
|
|
566
|
+
const parser = opts?.includeMetadata ? parseWithMetadata : parseBasic;
|
|
567
|
+
const r = await executeAndParse(script, parser, opts);
|
|
568
|
+
return r.success ? r.data ?? null : null;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
// src/osascript/scripts/finderContext.ts
|
|
572
|
+
var SEC2 = "\xA7\xA7\xA7";
|
|
573
|
+
var FLD2 = "|||";
|
|
574
|
+
var ITM2 = ":::";
|
|
575
|
+
var SCRIPT = `
|
|
576
|
+
set d to "${FLD2}"
|
|
577
|
+
set s to "${SEC2}"
|
|
578
|
+
set i to "${ITM2}"
|
|
579
|
+
|
|
580
|
+
-- Check if Finder is frontmost
|
|
581
|
+
set isFinderFront to "0"
|
|
582
|
+
tell application "System Events"
|
|
583
|
+
set finderRunning to (exists process "Finder")
|
|
584
|
+
if finderRunning then
|
|
585
|
+
try
|
|
586
|
+
set frontApp to bundle identifier of (first application process whose frontmost is true)
|
|
587
|
+
if frontApp is "com.apple.finder" then
|
|
588
|
+
set isFinderFront to "1"
|
|
589
|
+
end if
|
|
590
|
+
end try
|
|
591
|
+
end if
|
|
592
|
+
end tell
|
|
593
|
+
|
|
594
|
+
set sec0 to isFinderFront
|
|
595
|
+
set sec1 to ""
|
|
596
|
+
set sec2 to ""
|
|
597
|
+
|
|
598
|
+
if not finderRunning then
|
|
599
|
+
return sec0 & s & sec1 & s & sec2
|
|
600
|
+
end if
|
|
601
|
+
|
|
602
|
+
tell application "Finder"
|
|
603
|
+
-- Get all Finder windows
|
|
604
|
+
set wc to count of Finder windows
|
|
605
|
+
if wc > 0 then
|
|
606
|
+
set L to {}
|
|
607
|
+
repeat with idx from 1 to wc
|
|
608
|
+
set w to Finder window idx
|
|
609
|
+
set wName to name of w
|
|
610
|
+
set wPath to ""
|
|
611
|
+
try
|
|
612
|
+
set wPath to POSIX path of (target of w as alias)
|
|
613
|
+
on error
|
|
614
|
+
-- Special view (Recents, AirDrop, Search, Tags, etc.)
|
|
615
|
+
set wPath to "special:" & wName
|
|
616
|
+
end try
|
|
617
|
+
set end of L to wName & d & wPath & d & (idx as string)
|
|
618
|
+
end repeat
|
|
619
|
+
set {tid, AppleScript's text item delimiters} to {AppleScript's text item delimiters, i}
|
|
620
|
+
set sec1 to L as string
|
|
621
|
+
set AppleScript's text item delimiters to tid
|
|
622
|
+
end if
|
|
623
|
+
|
|
624
|
+
-- Get selection only if Finder is frontmost
|
|
625
|
+
if isFinderFront is "1" then
|
|
626
|
+
set sel to selection
|
|
627
|
+
set sc to count of sel
|
|
628
|
+
if sc > 0 then
|
|
629
|
+
set L to {}
|
|
630
|
+
repeat with j from 1 to sc
|
|
631
|
+
if j > 100 then exit repeat
|
|
632
|
+
set f to item j of sel
|
|
633
|
+
try
|
|
634
|
+
set end of L to POSIX path of (f as alias)
|
|
635
|
+
end try
|
|
636
|
+
end repeat
|
|
637
|
+
set {tid, AppleScript's text item delimiters} to {AppleScript's text item delimiters, i}
|
|
638
|
+
set sec2 to L as string
|
|
639
|
+
set AppleScript's text item delimiters to tid
|
|
640
|
+
end if
|
|
641
|
+
end if
|
|
642
|
+
end tell
|
|
643
|
+
|
|
644
|
+
return sec0 & s & sec1 & s & sec2
|
|
645
|
+
`;
|
|
646
|
+
function parseOutput(out) {
|
|
647
|
+
const sections = out.split(SEC2);
|
|
648
|
+
const isFinderFrontmost = sections[0]?.trim() === "1";
|
|
649
|
+
const windows = [];
|
|
650
|
+
if (sections[1]?.trim()) {
|
|
651
|
+
for (const win of sections[1].split(ITM2)) {
|
|
652
|
+
const parts = win.split(FLD2);
|
|
653
|
+
if (parts.length >= 3) {
|
|
654
|
+
const rawPath = parts[1] ?? "";
|
|
655
|
+
const isSpecial = rawPath.startsWith("special:");
|
|
656
|
+
windows.push({
|
|
657
|
+
name: parts[0] ?? "",
|
|
658
|
+
path: isSpecial ? null : rawPath,
|
|
659
|
+
index: parseInt(parts[2] ?? "0", 10),
|
|
660
|
+
isSpecialView: isSpecial
|
|
661
|
+
});
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
const selectedPaths = [];
|
|
666
|
+
if (sections[2]?.trim()) {
|
|
667
|
+
for (const p of sections[2].split(ITM2)) {
|
|
668
|
+
if (p.trim()) {
|
|
669
|
+
selectedPaths.push(p);
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
let frontWindow = null;
|
|
674
|
+
if (isFinderFrontmost && windows.length > 0) {
|
|
675
|
+
const first = windows[0];
|
|
676
|
+
frontWindow = {
|
|
677
|
+
name: first.name,
|
|
678
|
+
path: first.path,
|
|
679
|
+
isSpecialView: first.isSpecialView
|
|
680
|
+
};
|
|
681
|
+
}
|
|
682
|
+
return {
|
|
683
|
+
windows,
|
|
684
|
+
frontWindow,
|
|
685
|
+
selectedPaths,
|
|
686
|
+
isFinderFrontmost,
|
|
687
|
+
windowCount: windows.length
|
|
688
|
+
};
|
|
689
|
+
}
|
|
690
|
+
async function getFinderContext(options) {
|
|
691
|
+
if (!isOsascriptAvailable()) {
|
|
692
|
+
return null;
|
|
693
|
+
}
|
|
694
|
+
const result = await executeAndParse(SCRIPT, parseOutput, options);
|
|
695
|
+
return result.success ? result.data ?? null : null;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
// src/osascript/scripts/frontmostApp.ts
|
|
699
|
+
var DELIMITER = "|||";
|
|
700
|
+
var SCRIPT2 = `
|
|
701
|
+
tell application "System Events"
|
|
702
|
+
set frontApp to first application process whose frontmost is true
|
|
703
|
+
set appName to displayed name of frontApp
|
|
704
|
+
set appId to bundle identifier of frontApp
|
|
705
|
+
try
|
|
706
|
+
set appPath to POSIX path of (file of frontApp as alias)
|
|
707
|
+
on error
|
|
708
|
+
set appPath to ""
|
|
709
|
+
end try
|
|
710
|
+
return appName & "${DELIMITER}" & appId & "${DELIMITER}" & appPath
|
|
711
|
+
end tell
|
|
712
|
+
`;
|
|
713
|
+
function parseOutput2(output) {
|
|
714
|
+
const parts = output.split(DELIMITER);
|
|
715
|
+
const name = parts[0] ?? "";
|
|
716
|
+
const bundleId = parts[1] ?? "";
|
|
717
|
+
const path2 = parts[2] ?? "";
|
|
718
|
+
return {
|
|
719
|
+
name,
|
|
720
|
+
bundleId,
|
|
721
|
+
isFinder: bundleId === "com.apple.finder",
|
|
722
|
+
path: path2
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
async function getFrontmostApp(options) {
|
|
726
|
+
if (!isOsascriptAvailable()) {
|
|
727
|
+
return null;
|
|
728
|
+
}
|
|
729
|
+
const result = await executeAndParse(SCRIPT2, parseOutput2, options);
|
|
730
|
+
if (result.success && result.data) {
|
|
731
|
+
return result.data;
|
|
732
|
+
}
|
|
733
|
+
return null;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
// src/osascript/scripts/finderSelection.ts
|
|
737
|
+
var FIELD_DELIMITER = "|||";
|
|
738
|
+
var ITEM_DELIMITER = ":::";
|
|
739
|
+
var SCRIPT3 = `
|
|
740
|
+
tell application "System Events"
|
|
741
|
+
set finderRunning to (exists process "Finder")
|
|
742
|
+
end tell
|
|
743
|
+
|
|
744
|
+
if finderRunning is false then
|
|
745
|
+
return ""
|
|
746
|
+
end if
|
|
747
|
+
|
|
748
|
+
tell application "Finder"
|
|
749
|
+
set sel to selection
|
|
750
|
+
if (count of sel) = 0 then
|
|
751
|
+
return ""
|
|
752
|
+
end if
|
|
753
|
+
set output to ""
|
|
754
|
+
repeat with f in sel
|
|
755
|
+
set p to POSIX path of (f as alias)
|
|
756
|
+
set n to name of f
|
|
757
|
+
set k to class of f as string
|
|
758
|
+
if output is not "" then
|
|
759
|
+
set output to output & "${ITEM_DELIMITER}"
|
|
760
|
+
end if
|
|
761
|
+
set output to output & p & "${FIELD_DELIMITER}" & n & "${FIELD_DELIMITER}" & k
|
|
762
|
+
end repeat
|
|
763
|
+
return output
|
|
764
|
+
end tell
|
|
765
|
+
`;
|
|
766
|
+
function parseOutput3(output) {
|
|
767
|
+
if (!output || output.trim() === "") {
|
|
768
|
+
return {
|
|
769
|
+
paths: [],
|
|
770
|
+
count: 0,
|
|
771
|
+
items: []
|
|
772
|
+
};
|
|
773
|
+
}
|
|
774
|
+
const itemStrings = output.split(ITEM_DELIMITER);
|
|
775
|
+
const items = [];
|
|
776
|
+
const paths = [];
|
|
777
|
+
for (const itemStr of itemStrings) {
|
|
778
|
+
const parts = itemStr.split(FIELD_DELIMITER);
|
|
779
|
+
if (parts.length >= 2) {
|
|
780
|
+
const path2 = parts[0] ?? "";
|
|
781
|
+
const name = parts[1] ?? "";
|
|
782
|
+
const classType = parts[2] ?? "";
|
|
783
|
+
const isFolder = classType.toLowerCase().includes("folder");
|
|
784
|
+
paths.push(path2);
|
|
785
|
+
items.push({
|
|
786
|
+
name,
|
|
787
|
+
path: path2,
|
|
788
|
+
isFolder
|
|
789
|
+
});
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
return {
|
|
793
|
+
paths,
|
|
794
|
+
count: items.length,
|
|
795
|
+
items
|
|
796
|
+
};
|
|
797
|
+
}
|
|
798
|
+
async function getFinderSelection(options) {
|
|
799
|
+
if (!isOsascriptAvailable()) {
|
|
800
|
+
return null;
|
|
801
|
+
}
|
|
802
|
+
const result = await executeAndParse(SCRIPT3, parseOutput3, options);
|
|
803
|
+
if (result.success && result.data) {
|
|
804
|
+
return result.data;
|
|
805
|
+
}
|
|
806
|
+
return null;
|
|
807
|
+
}
|
|
808
|
+
var CURRENT_FOLDER_SCRIPT = `
|
|
809
|
+
tell application "System Events"
|
|
810
|
+
set finderRunning to (exists process "Finder")
|
|
811
|
+
end tell
|
|
812
|
+
|
|
813
|
+
if finderRunning is false then
|
|
814
|
+
return ""
|
|
815
|
+
end if
|
|
816
|
+
|
|
817
|
+
tell application "Finder"
|
|
818
|
+
try
|
|
819
|
+
set frontWindow to front Finder window
|
|
820
|
+
set folderPath to POSIX path of (target of frontWindow as alias)
|
|
821
|
+
return folderPath
|
|
822
|
+
on error
|
|
823
|
+
return ""
|
|
824
|
+
end try
|
|
825
|
+
end tell
|
|
826
|
+
`;
|
|
827
|
+
async function getFinderCurrentFolder(options) {
|
|
828
|
+
if (!isOsascriptAvailable()) {
|
|
829
|
+
return null;
|
|
830
|
+
}
|
|
831
|
+
const result = await executeAndParse(
|
|
832
|
+
CURRENT_FOLDER_SCRIPT,
|
|
833
|
+
(output) => output.trim() || null,
|
|
834
|
+
options
|
|
835
|
+
);
|
|
836
|
+
if (result.success) {
|
|
837
|
+
return result.data ?? null;
|
|
838
|
+
}
|
|
839
|
+
return null;
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
// src/osascript/scripts/finderWindows.ts
|
|
843
|
+
var FIELD_DELIMITER2 = "|||";
|
|
844
|
+
var ITEM_DELIMITER2 = ":::";
|
|
845
|
+
var SCRIPT4 = `
|
|
846
|
+
tell application "System Events"
|
|
847
|
+
set finderRunning to (exists process "Finder")
|
|
848
|
+
end tell
|
|
849
|
+
|
|
850
|
+
if finderRunning is false then
|
|
851
|
+
return ""
|
|
852
|
+
end if
|
|
853
|
+
|
|
854
|
+
tell application "Finder"
|
|
855
|
+
set windowList to every Finder window
|
|
856
|
+
if (count of windowList) = 0 then
|
|
857
|
+
return ""
|
|
858
|
+
end if
|
|
859
|
+
set output to ""
|
|
860
|
+
set idx to 1
|
|
861
|
+
repeat with w in windowList
|
|
862
|
+
set windowName to name of w
|
|
863
|
+
set windowPath to ""
|
|
864
|
+
try
|
|
865
|
+
set windowPath to POSIX path of (target of w as alias)
|
|
866
|
+
on error
|
|
867
|
+
-- Special view (Recents, Search, etc.) - mark with special: prefix
|
|
868
|
+
set windowPath to "special:" & windowName
|
|
869
|
+
end try
|
|
870
|
+
if output is not "" then
|
|
871
|
+
set output to output & "${ITEM_DELIMITER2}"
|
|
872
|
+
end if
|
|
873
|
+
set output to output & windowName & "${FIELD_DELIMITER2}" & windowPath & "${FIELD_DELIMITER2}" & idx
|
|
874
|
+
set idx to idx + 1
|
|
875
|
+
end repeat
|
|
876
|
+
return output
|
|
877
|
+
end tell
|
|
878
|
+
`;
|
|
879
|
+
function parseOutput4(output) {
|
|
880
|
+
if (!output || output.trim() === "") {
|
|
881
|
+
return [];
|
|
882
|
+
}
|
|
883
|
+
const itemStrings = output.split(ITEM_DELIMITER2);
|
|
884
|
+
const windows = [];
|
|
885
|
+
for (const itemStr of itemStrings) {
|
|
886
|
+
const parts = itemStr.split(FIELD_DELIMITER2);
|
|
887
|
+
if (parts.length >= 3) {
|
|
888
|
+
const pathValue = parts[1] ?? "";
|
|
889
|
+
const isSpecial = pathValue.startsWith("special:");
|
|
890
|
+
windows.push({
|
|
891
|
+
name: parts[0] ?? "",
|
|
892
|
+
path: isSpecial ? null : pathValue,
|
|
893
|
+
index: parseInt(parts[2] ?? "0", 10),
|
|
894
|
+
isSpecialView: isSpecial
|
|
895
|
+
});
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
return windows;
|
|
899
|
+
}
|
|
900
|
+
async function getFinderWindows(options) {
|
|
901
|
+
if (!isOsascriptAvailable()) {
|
|
902
|
+
return null;
|
|
903
|
+
}
|
|
904
|
+
const result = await executeAndParse(SCRIPT4, parseOutput4, options);
|
|
905
|
+
if (result.success && result.data) {
|
|
906
|
+
return result.data;
|
|
907
|
+
}
|
|
908
|
+
return null;
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
// src/osascript/scripts/fileMetadata.ts
|
|
912
|
+
var DELIMITER2 = "|||";
|
|
913
|
+
function buildScript(filePath) {
|
|
914
|
+
const escapedPath = escapeForAppleScript(filePath);
|
|
915
|
+
return `
|
|
916
|
+
tell application "System Events"
|
|
917
|
+
set f to disk item (POSIX file "${escapedPath}")
|
|
918
|
+
set n to name of f
|
|
919
|
+
set p to "${escapedPath}"
|
|
920
|
+
try
|
|
921
|
+
set s to size of f
|
|
922
|
+
on error
|
|
923
|
+
set s to 0
|
|
924
|
+
end try
|
|
925
|
+
set isDir to (class of f is folder) as string
|
|
926
|
+
try
|
|
927
|
+
set c to creation date of f as string
|
|
928
|
+
on error
|
|
929
|
+
set c to ""
|
|
930
|
+
end try
|
|
931
|
+
try
|
|
932
|
+
set m to modification date of f as string
|
|
933
|
+
on error
|
|
934
|
+
set m to ""
|
|
935
|
+
end try
|
|
936
|
+
try
|
|
937
|
+
set ext to name extension of f
|
|
938
|
+
on error
|
|
939
|
+
set ext to ""
|
|
940
|
+
end try
|
|
941
|
+
try
|
|
942
|
+
set k to kind of f
|
|
943
|
+
on error
|
|
944
|
+
set k to ""
|
|
945
|
+
end try
|
|
946
|
+
return n & "${DELIMITER2}" & p & "${DELIMITER2}" & s & "${DELIMITER2}" & isDir & "${DELIMITER2}" & c & "${DELIMITER2}" & m & "${DELIMITER2}" & ext & "${DELIMITER2}" & k
|
|
947
|
+
end tell
|
|
948
|
+
`;
|
|
949
|
+
}
|
|
950
|
+
function parseOutput5(output) {
|
|
951
|
+
const parts = output.split(DELIMITER2);
|
|
952
|
+
return {
|
|
953
|
+
name: parts[0] ?? "",
|
|
954
|
+
path: parts[1] ?? "",
|
|
955
|
+
size: parseInt(parts[2] ?? "0", 10) || 0,
|
|
956
|
+
isFolder: (parts[3] ?? "").toLowerCase() === "true",
|
|
957
|
+
createdAt: parts[4] ?? "",
|
|
958
|
+
modifiedAt: parts[5] ?? "",
|
|
959
|
+
extension: parts[6] ?? "",
|
|
960
|
+
kind: parts[7] ?? ""
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
async function getFileMetadata(filePath, options) {
|
|
964
|
+
if (!isOsascriptAvailable()) {
|
|
965
|
+
return null;
|
|
966
|
+
}
|
|
967
|
+
const script = buildScript(filePath);
|
|
968
|
+
const result = await executeAndParse(script, parseOutput5, options);
|
|
969
|
+
if (result.success && result.data) {
|
|
970
|
+
return result.data;
|
|
971
|
+
}
|
|
972
|
+
return null;
|
|
973
|
+
}
|
|
974
|
+
async function getFilesMetadata(filePaths, options) {
|
|
975
|
+
if (!isOsascriptAvailable()) {
|
|
976
|
+
return filePaths.map(() => null);
|
|
977
|
+
}
|
|
978
|
+
const results = await Promise.all(
|
|
979
|
+
filePaths.map((path2) => getFileMetadata(path2, options))
|
|
980
|
+
);
|
|
981
|
+
return results;
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
// src/osascript/scripts/clipboard.ts
|
|
985
|
+
var DELIMITER3 = "|||";
|
|
986
|
+
var FILE_DELIMITER = ":::";
|
|
987
|
+
var TEXT_SCRIPT = `
|
|
988
|
+
try
|
|
989
|
+
set clipText to the clipboard as text
|
|
990
|
+
return clipText
|
|
991
|
+
on error
|
|
992
|
+
return ""
|
|
993
|
+
end try
|
|
994
|
+
`;
|
|
995
|
+
var FILES_SCRIPT = `
|
|
996
|
+
try
|
|
997
|
+
set clipFiles to the clipboard as alias list
|
|
998
|
+
set output to ""
|
|
999
|
+
repeat with f in clipFiles
|
|
1000
|
+
set p to POSIX path of (f as alias)
|
|
1001
|
+
if output is not "" then
|
|
1002
|
+
set output to output & "${FILE_DELIMITER}"
|
|
1003
|
+
end if
|
|
1004
|
+
set output to output & p
|
|
1005
|
+
end repeat
|
|
1006
|
+
if output is "" then
|
|
1007
|
+
return "NOFILES${DELIMITER3}"
|
|
1008
|
+
end if
|
|
1009
|
+
return "FILES${DELIMITER3}" & output
|
|
1010
|
+
on error
|
|
1011
|
+
return "NOFILES${DELIMITER3}"
|
|
1012
|
+
end try
|
|
1013
|
+
`;
|
|
1014
|
+
var IMAGE_SCRIPT = `
|
|
1015
|
+
try
|
|
1016
|
+
set imgData to the clipboard as \xABclass PNGf\xBB
|
|
1017
|
+
return "1"
|
|
1018
|
+
on error
|
|
1019
|
+
try
|
|
1020
|
+
set imgData to the clipboard as TIFF picture
|
|
1021
|
+
return "1"
|
|
1022
|
+
on error
|
|
1023
|
+
return "0"
|
|
1024
|
+
end try
|
|
1025
|
+
end try
|
|
1026
|
+
`;
|
|
1027
|
+
function parseFilesOutput(output) {
|
|
1028
|
+
if (output.startsWith("FILES" + DELIMITER3)) {
|
|
1029
|
+
const pathsPart = output.substring(("FILES" + DELIMITER3).length);
|
|
1030
|
+
if (pathsPart.trim()) {
|
|
1031
|
+
const paths = pathsPart.split(FILE_DELIMITER).filter((p) => p.trim());
|
|
1032
|
+
return { hasFiles: paths.length > 0, filePaths: paths };
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
return { hasFiles: false, filePaths: [] };
|
|
1036
|
+
}
|
|
1037
|
+
async function getClipboardContent(options) {
|
|
1038
|
+
if (!isOsascriptAvailable()) {
|
|
1039
|
+
return null;
|
|
1040
|
+
}
|
|
1041
|
+
const [textResult, filesResult, imageResult] = await Promise.all([
|
|
1042
|
+
executeAndParse(TEXT_SCRIPT, (output) => output || null, options),
|
|
1043
|
+
executeAndParse(FILES_SCRIPT, parseFilesOutput, options),
|
|
1044
|
+
executeAndParse(IMAGE_SCRIPT, (output) => output.trim() === "1", options)
|
|
1045
|
+
]);
|
|
1046
|
+
const text = textResult.success ? textResult.data : null;
|
|
1047
|
+
const filesData = filesResult.success && filesResult.data ? filesResult.data : { hasFiles: false, filePaths: [] };
|
|
1048
|
+
const hasImage = imageResult.success ? imageResult.data ?? false : false;
|
|
1049
|
+
return {
|
|
1050
|
+
text: text ?? null,
|
|
1051
|
+
hasFiles: filesData.hasFiles,
|
|
1052
|
+
filePaths: filesData.filePaths,
|
|
1053
|
+
hasImage
|
|
1054
|
+
};
|
|
1055
|
+
}
|
|
1056
|
+
async function getClipboardText(options) {
|
|
1057
|
+
if (!isOsascriptAvailable()) {
|
|
1058
|
+
return null;
|
|
1059
|
+
}
|
|
1060
|
+
const result = await executeAndParse(TEXT_SCRIPT, (output) => output || null, options);
|
|
1061
|
+
if (result.success) {
|
|
1062
|
+
return result.data ?? null;
|
|
1063
|
+
}
|
|
1064
|
+
return null;
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
// src/osascript/scripts/desktopItems.ts
|
|
1068
|
+
var FIELD_DELIMITER3 = "|||";
|
|
1069
|
+
var ITEM_DELIMITER3 = ":::";
|
|
1070
|
+
var SCRIPT5 = `
|
|
1071
|
+
tell application "System Events"
|
|
1072
|
+
set finderRunning to (exists process "Finder")
|
|
1073
|
+
end tell
|
|
1074
|
+
|
|
1075
|
+
if finderRunning is false then
|
|
1076
|
+
return ""
|
|
1077
|
+
end if
|
|
1078
|
+
|
|
1079
|
+
tell application "Finder"
|
|
1080
|
+
set desktopItems to every item of desktop
|
|
1081
|
+
if (count of desktopItems) = 0 then
|
|
1082
|
+
return ""
|
|
1083
|
+
end if
|
|
1084
|
+
set output to ""
|
|
1085
|
+
repeat with f in desktopItems
|
|
1086
|
+
set n to name of f
|
|
1087
|
+
set p to POSIX path of (f as alias)
|
|
1088
|
+
set k to class of f as string
|
|
1089
|
+
if output is not "" then
|
|
1090
|
+
set output to output & "${ITEM_DELIMITER3}"
|
|
1091
|
+
end if
|
|
1092
|
+
set output to output & n & "${FIELD_DELIMITER3}" & p & "${FIELD_DELIMITER3}" & k
|
|
1093
|
+
end repeat
|
|
1094
|
+
return output
|
|
1095
|
+
end tell
|
|
1096
|
+
`;
|
|
1097
|
+
function parseOutput6(output) {
|
|
1098
|
+
if (!output || output.trim() === "") {
|
|
1099
|
+
return [];
|
|
1100
|
+
}
|
|
1101
|
+
const itemStrings = output.split(ITEM_DELIMITER3);
|
|
1102
|
+
const items = [];
|
|
1103
|
+
for (const itemStr of itemStrings) {
|
|
1104
|
+
const parts = itemStr.split(FIELD_DELIMITER3);
|
|
1105
|
+
if (parts.length >= 2) {
|
|
1106
|
+
const name = parts[0] ?? "";
|
|
1107
|
+
const path2 = parts[1] ?? "";
|
|
1108
|
+
const classType = parts[2] ?? "";
|
|
1109
|
+
items.push({
|
|
1110
|
+
name,
|
|
1111
|
+
path: path2,
|
|
1112
|
+
isFolder: classType.toLowerCase().includes("folder")
|
|
1113
|
+
});
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
return items;
|
|
1117
|
+
}
|
|
1118
|
+
async function getDesktopItems(options) {
|
|
1119
|
+
if (!isOsascriptAvailable()) {
|
|
1120
|
+
return null;
|
|
1121
|
+
}
|
|
1122
|
+
const result = await executeAndParse(SCRIPT5, parseOutput6, options);
|
|
1123
|
+
if (result.success && result.data) {
|
|
1124
|
+
return result.data;
|
|
1125
|
+
}
|
|
1126
|
+
return null;
|
|
1127
|
+
}
|
|
1128
|
+
async function getDesktopPath(options) {
|
|
1129
|
+
if (!isOsascriptAvailable()) {
|
|
1130
|
+
return null;
|
|
1131
|
+
}
|
|
1132
|
+
const script = `try
|
|
1133
|
+
return do shell script "echo $HOME/Desktop/"
|
|
1134
|
+
on error
|
|
1135
|
+
return ""
|
|
1136
|
+
end try`;
|
|
1137
|
+
const result = await executeAndParse(script, (output) => output.trim() || null, options);
|
|
1138
|
+
if (result.success) {
|
|
1139
|
+
return result.data ?? null;
|
|
1140
|
+
}
|
|
1141
|
+
return null;
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
// src/osascript/scripts/recentFiles.ts
|
|
1145
|
+
var FIELD_DELIMITER4 = "|||";
|
|
1146
|
+
var ITEM_DELIMITER4 = ":::";
|
|
1147
|
+
function buildScript2(limit) {
|
|
1148
|
+
return `
|
|
1149
|
+
tell application "System Events"
|
|
1150
|
+
set finderRunning to (exists process "Finder")
|
|
1151
|
+
end tell
|
|
1152
|
+
|
|
1153
|
+
if finderRunning is false then
|
|
1154
|
+
return ""
|
|
1155
|
+
end if
|
|
1156
|
+
|
|
1157
|
+
tell application "Finder"
|
|
1158
|
+
try
|
|
1159
|
+
set recentFolder to folder "Recents" of home
|
|
1160
|
+
set recentItems to every item of recentFolder
|
|
1161
|
+
set itemCount to count of recentItems
|
|
1162
|
+
if itemCount > ${limit} then
|
|
1163
|
+
set itemCount to ${limit}
|
|
1164
|
+
end if
|
|
1165
|
+
if itemCount = 0 then
|
|
1166
|
+
return ""
|
|
1167
|
+
end if
|
|
1168
|
+
set output to ""
|
|
1169
|
+
repeat with i from 1 to itemCount
|
|
1170
|
+
set f to item i of recentItems
|
|
1171
|
+
try
|
|
1172
|
+
set n to name of f
|
|
1173
|
+
set p to POSIX path of (f as alias)
|
|
1174
|
+
set m to modification date of f as string
|
|
1175
|
+
if output is not "" then
|
|
1176
|
+
set output to output & "${ITEM_DELIMITER4}"
|
|
1177
|
+
end if
|
|
1178
|
+
set output to output & n & "${FIELD_DELIMITER4}" & p & "${FIELD_DELIMITER4}" & m
|
|
1179
|
+
end try
|
|
1180
|
+
end repeat
|
|
1181
|
+
return output
|
|
1182
|
+
on error
|
|
1183
|
+
return ""
|
|
1184
|
+
end try
|
|
1185
|
+
end tell
|
|
1186
|
+
`;
|
|
1187
|
+
}
|
|
1188
|
+
var RECENT_DOCUMENTS_SCRIPT = `
|
|
1189
|
+
try
|
|
1190
|
+
set recentApps to paragraphs of (do shell script "mdfind -onlyin ~ 'kMDItemLastUsedDate >= $time.today(-7)' | head -50")
|
|
1191
|
+
set output to ""
|
|
1192
|
+
repeat with filePath in recentApps
|
|
1193
|
+
if filePath is not "" then
|
|
1194
|
+
try
|
|
1195
|
+
tell application "System Events"
|
|
1196
|
+
set f to disk item (POSIX file filePath)
|
|
1197
|
+
set n to name of f
|
|
1198
|
+
set m to modification date of f as string
|
|
1199
|
+
end tell
|
|
1200
|
+
if output is not "" then
|
|
1201
|
+
set output to output & "${ITEM_DELIMITER4}"
|
|
1202
|
+
end if
|
|
1203
|
+
set output to output & n & "${FIELD_DELIMITER4}" & filePath & "${FIELD_DELIMITER4}" & m
|
|
1204
|
+
end try
|
|
1205
|
+
end if
|
|
1206
|
+
end repeat
|
|
1207
|
+
return output
|
|
1208
|
+
on error
|
|
1209
|
+
return ""
|
|
1210
|
+
end try
|
|
1211
|
+
`;
|
|
1212
|
+
function parseOutput7(output) {
|
|
1213
|
+
if (!output || output.trim() === "") {
|
|
1214
|
+
return [];
|
|
1215
|
+
}
|
|
1216
|
+
const itemStrings = output.split(ITEM_DELIMITER4);
|
|
1217
|
+
const items = [];
|
|
1218
|
+
for (const itemStr of itemStrings) {
|
|
1219
|
+
const parts = itemStr.split(FIELD_DELIMITER4);
|
|
1220
|
+
if (parts.length >= 2) {
|
|
1221
|
+
items.push({
|
|
1222
|
+
name: parts[0] ?? "",
|
|
1223
|
+
path: parts[1] ?? "",
|
|
1224
|
+
accessedAt: parts[2] ?? ""
|
|
1225
|
+
});
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
return items;
|
|
1229
|
+
}
|
|
1230
|
+
async function getRecentFiles(limit = 20, options) {
|
|
1231
|
+
if (!isOsascriptAvailable()) {
|
|
1232
|
+
return null;
|
|
1233
|
+
}
|
|
1234
|
+
const script = buildScript2(limit);
|
|
1235
|
+
const result = await executeAndParse(script, parseOutput7, options);
|
|
1236
|
+
if (result.success && result.data) {
|
|
1237
|
+
return result.data;
|
|
1238
|
+
}
|
|
1239
|
+
return null;
|
|
1240
|
+
}
|
|
1241
|
+
async function getRecentDocuments(options) {
|
|
1242
|
+
if (!isOsascriptAvailable()) {
|
|
1243
|
+
return null;
|
|
1244
|
+
}
|
|
1245
|
+
const result = await executeAndParse(RECENT_DOCUMENTS_SCRIPT, parseOutput7, options);
|
|
1246
|
+
if (result.success && result.data) {
|
|
1247
|
+
return result.data;
|
|
1248
|
+
}
|
|
1249
|
+
return null;
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
// src/osascript/scripts/runningApps.ts
|
|
1253
|
+
var FIELD_DELIMITER5 = "|||";
|
|
1254
|
+
var ITEM_DELIMITER5 = ":::";
|
|
1255
|
+
var SCRIPT6 = `
|
|
1256
|
+
tell application "System Events"
|
|
1257
|
+
set appList to every application process
|
|
1258
|
+
set output to ""
|
|
1259
|
+
repeat with proc in appList
|
|
1260
|
+
try
|
|
1261
|
+
set appName to name of proc
|
|
1262
|
+
set appId to bundle identifier of proc
|
|
1263
|
+
set isHidden to not (visible of proc)
|
|
1264
|
+
set isFront to frontmost of proc
|
|
1265
|
+
if output is not "" then
|
|
1266
|
+
set output to output & "${ITEM_DELIMITER5}"
|
|
1267
|
+
end if
|
|
1268
|
+
set output to output & appName & "${FIELD_DELIMITER5}" & appId & "${FIELD_DELIMITER5}" & (isHidden as string) & "${FIELD_DELIMITER5}" & (isFront as string)
|
|
1269
|
+
end try
|
|
1270
|
+
end repeat
|
|
1271
|
+
return output
|
|
1272
|
+
end tell
|
|
1273
|
+
`;
|
|
1274
|
+
function parseOutput8(output) {
|
|
1275
|
+
if (!output || output.trim() === "") {
|
|
1276
|
+
return [];
|
|
1277
|
+
}
|
|
1278
|
+
const itemStrings = output.split(ITEM_DELIMITER5);
|
|
1279
|
+
const apps = [];
|
|
1280
|
+
for (const itemStr of itemStrings) {
|
|
1281
|
+
const parts = itemStr.split(FIELD_DELIMITER5);
|
|
1282
|
+
if (parts.length >= 4) {
|
|
1283
|
+
apps.push({
|
|
1284
|
+
name: parts[0] ?? "",
|
|
1285
|
+
bundleId: parts[1] ?? "",
|
|
1286
|
+
isHidden: (parts[2] ?? "").toLowerCase() === "true",
|
|
1287
|
+
isFrontmost: (parts[3] ?? "").toLowerCase() === "true"
|
|
1288
|
+
});
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
return apps;
|
|
1292
|
+
}
|
|
1293
|
+
async function getRunningApps(options) {
|
|
1294
|
+
if (!isOsascriptAvailable()) {
|
|
1295
|
+
return null;
|
|
1296
|
+
}
|
|
1297
|
+
const result = await executeAndParse(SCRIPT6, parseOutput8, options);
|
|
1298
|
+
if (result.success && result.data) {
|
|
1299
|
+
return result.data;
|
|
1300
|
+
}
|
|
1301
|
+
return null;
|
|
1302
|
+
}
|
|
1303
|
+
async function isAppRunning(appName, options) {
|
|
1304
|
+
const apps = await getRunningApps(options);
|
|
1305
|
+
if (!apps) {
|
|
1306
|
+
return false;
|
|
1307
|
+
}
|
|
1308
|
+
const lowerName = appName.toLowerCase();
|
|
1309
|
+
return apps.some(
|
|
1310
|
+
(app) => app.name.toLowerCase() === lowerName || app.bundleId.toLowerCase() === lowerName
|
|
1311
|
+
);
|
|
1312
|
+
}
|
|
1313
|
+
async function getFrontmostFromRunning(options) {
|
|
1314
|
+
const apps = await getRunningApps(options);
|
|
1315
|
+
if (!apps) {
|
|
1316
|
+
return null;
|
|
1317
|
+
}
|
|
1318
|
+
return apps.find((app) => app.isFrontmost) ?? null;
|
|
1319
|
+
}
|
|
1320
|
+
|
|
1321
|
+
// src/osascript/scripts/fileContent.ts
|
|
1322
|
+
var DELIMITER4 = "\xA7\xA7\xA7";
|
|
1323
|
+
async function readFileContent(filePath, opts) {
|
|
1324
|
+
if (!isOsascriptAvailable()) return null;
|
|
1325
|
+
const maxBytes = opts?.maxBytes ?? 1048576;
|
|
1326
|
+
const encoding = opts?.encoding ?? "utf8";
|
|
1327
|
+
const script = `
|
|
1328
|
+
set filePath to "${filePath.replace(/"/g, '\\"')}"
|
|
1329
|
+
set maxSize to ${maxBytes}
|
|
1330
|
+
set d to "${DELIMITER4}"
|
|
1331
|
+
|
|
1332
|
+
try
|
|
1333
|
+
set fileRef to POSIX file filePath
|
|
1334
|
+
|
|
1335
|
+
-- Get file size first
|
|
1336
|
+
tell application "System Events"
|
|
1337
|
+
set fileSize to size of (disk item filePath)
|
|
1338
|
+
end tell
|
|
1339
|
+
|
|
1340
|
+
-- Check size limit
|
|
1341
|
+
if fileSize > maxSize then
|
|
1342
|
+
return "ERROR" & d & "File too large: " & fileSize & " bytes (max: " & maxSize & ")"
|
|
1343
|
+
end if
|
|
1344
|
+
|
|
1345
|
+
-- Read file content
|
|
1346
|
+
set fileContent to read fileRef as \xABclass utf8\xBB
|
|
1347
|
+
|
|
1348
|
+
return "OK" & d & fileSize & d & fileContent
|
|
1349
|
+
on error errMsg
|
|
1350
|
+
return "ERROR" & d & errMsg
|
|
1351
|
+
end try
|
|
1352
|
+
`;
|
|
1353
|
+
const parser = (out) => {
|
|
1354
|
+
const parts = out.split(DELIMITER4);
|
|
1355
|
+
const status = parts[0]?.trim();
|
|
1356
|
+
if (status === "ERROR") {
|
|
1357
|
+
return {
|
|
1358
|
+
path: filePath,
|
|
1359
|
+
content: "",
|
|
1360
|
+
size: 0,
|
|
1361
|
+
success: false,
|
|
1362
|
+
error: parts[1]?.trim() || "Unknown error"
|
|
1363
|
+
};
|
|
1364
|
+
}
|
|
1365
|
+
return {
|
|
1366
|
+
path: filePath,
|
|
1367
|
+
content: parts.slice(2).join(DELIMITER4),
|
|
1368
|
+
// Content may contain delimiter
|
|
1369
|
+
size: parseInt(parts[1] ?? "0", 10),
|
|
1370
|
+
success: true
|
|
1371
|
+
};
|
|
1372
|
+
};
|
|
1373
|
+
const r = await executeAndParse(script, parser, opts);
|
|
1374
|
+
return r.success ? r.data ?? null : null;
|
|
1375
|
+
}
|
|
1376
|
+
async function readMultipleFiles(filePaths, opts) {
|
|
1377
|
+
if (!isOsascriptAvailable()) return [];
|
|
1378
|
+
const results = await Promise.all(
|
|
1379
|
+
filePaths.map((path2) => readFileContent(path2, opts))
|
|
1380
|
+
);
|
|
1381
|
+
return results.filter((r) => r !== null);
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
// src/osascript/index.ts
|
|
1385
|
+
async function getSystemContext(options) {
|
|
1386
|
+
if (!isOsascriptAvailable()) {
|
|
1387
|
+
return null;
|
|
1388
|
+
}
|
|
1389
|
+
const frontmostApp = await getFrontmostApp(options);
|
|
1390
|
+
if (!frontmostApp) {
|
|
1391
|
+
return null;
|
|
1392
|
+
}
|
|
1393
|
+
let finderSelection = null;
|
|
1394
|
+
let finderCurrentFolder = null;
|
|
1395
|
+
if (frontmostApp.isFinder) {
|
|
1396
|
+
[finderSelection, finderCurrentFolder] = await Promise.all([
|
|
1397
|
+
getFinderSelection(options),
|
|
1398
|
+
getFinderCurrentFolder(options)
|
|
1399
|
+
]);
|
|
1400
|
+
}
|
|
1401
|
+
const clipboard = await getClipboardContent(options);
|
|
1402
|
+
return {
|
|
1403
|
+
frontmostApp,
|
|
1404
|
+
finderSelection,
|
|
1405
|
+
finderCurrentFolder,
|
|
1406
|
+
clipboard: clipboard ?? { text: null, hasFiles: false, filePaths: [], hasImage: false }
|
|
1407
|
+
};
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
// src/index.ts
|
|
1411
|
+
var import_meta = {};
|
|
1412
|
+
var IS_MACOS2 = process.platform === "darwin";
|
|
50
1413
|
var IS_WINDOWS = process.platform === "win32";
|
|
51
1414
|
var PLATFORM_PACKAGES = {
|
|
52
1415
|
"darwin-arm64": "@simen-keyboard-listener/darwin-arm64",
|
|
@@ -83,7 +1446,7 @@ function getNativeAddon() {
|
|
|
83
1446
|
try {
|
|
84
1447
|
const candidate = localRequire(packageName);
|
|
85
1448
|
const hasCoreFunctions = candidate && typeof candidate.start === "function" && typeof candidate.stop === "function" && typeof candidate.isRunning === "function" && typeof candidate.checkPermission === "function";
|
|
86
|
-
const hasMacOSFunctions =
|
|
1449
|
+
const hasMacOSFunctions = IS_MACOS2 ? typeof candidate.getFocusedInputValue === "function" && typeof candidate.getFocusedInputSelectedText === "function" : true;
|
|
87
1450
|
if (hasCoreFunctions && hasMacOSFunctions) {
|
|
88
1451
|
nativeAddon = candidate;
|
|
89
1452
|
return nativeAddon;
|
|
@@ -200,7 +1563,7 @@ var NativeKeyboardListener = class _NativeKeyboardListener {
|
|
|
200
1563
|
}
|
|
201
1564
|
};
|
|
202
1565
|
function getGlobalKeyboardListener() {
|
|
203
|
-
if (!
|
|
1566
|
+
if (!IS_MACOS2 && !IS_WINDOWS) {
|
|
204
1567
|
throw new Error(`Unsupported platform for global keyboard listener: ${process.platform}`);
|
|
205
1568
|
}
|
|
206
1569
|
return NativeKeyboardListener.getInstance();
|
|
@@ -209,7 +1572,7 @@ function createGlobalKeyboardListener() {
|
|
|
209
1572
|
return getGlobalKeyboardListener();
|
|
210
1573
|
}
|
|
211
1574
|
function checkKeyboardPermission() {
|
|
212
|
-
if (!
|
|
1575
|
+
if (!IS_MACOS2 && !IS_WINDOWS) {
|
|
213
1576
|
return false;
|
|
214
1577
|
}
|
|
215
1578
|
try {
|
|
@@ -221,7 +1584,7 @@ function checkKeyboardPermission() {
|
|
|
221
1584
|
}
|
|
222
1585
|
var lastMacAccessibilitySettingsOpenTs = 0;
|
|
223
1586
|
function openMacAccessibilitySettings() {
|
|
224
|
-
if (!
|
|
1587
|
+
if (!IS_MACOS2) {
|
|
225
1588
|
return;
|
|
226
1589
|
}
|
|
227
1590
|
const now = Date.now();
|
|
@@ -230,7 +1593,7 @@ function openMacAccessibilitySettings() {
|
|
|
230
1593
|
}
|
|
231
1594
|
lastMacAccessibilitySettingsOpenTs = now;
|
|
232
1595
|
try {
|
|
233
|
-
(0,
|
|
1596
|
+
(0, import_node_child_process2.execFileSync)("open", ["x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility"], {
|
|
234
1597
|
stdio: "ignore"
|
|
235
1598
|
});
|
|
236
1599
|
} catch {
|
|
@@ -247,7 +1610,7 @@ function ensureAccessibilityPermission(addon) {
|
|
|
247
1610
|
return false;
|
|
248
1611
|
}
|
|
249
1612
|
function getFocusedInputValue() {
|
|
250
|
-
if (!
|
|
1613
|
+
if (!IS_MACOS2) {
|
|
251
1614
|
return null;
|
|
252
1615
|
}
|
|
253
1616
|
const addon = getNativeAddon();
|
|
@@ -261,7 +1624,7 @@ function getFocusedInputValue() {
|
|
|
261
1624
|
}
|
|
262
1625
|
}
|
|
263
1626
|
function getFocusedInputSelectedText() {
|
|
264
|
-
if (!
|
|
1627
|
+
if (!IS_MACOS2) {
|
|
265
1628
|
return null;
|
|
266
1629
|
}
|
|
267
1630
|
const addon = getNativeAddon();
|
|
@@ -275,7 +1638,7 @@ function getFocusedInputSelectedText() {
|
|
|
275
1638
|
}
|
|
276
1639
|
}
|
|
277
1640
|
function getContextJSON() {
|
|
278
|
-
if (!
|
|
1641
|
+
if (!IS_MACOS2) return null;
|
|
279
1642
|
const addon = getNativeAddon();
|
|
280
1643
|
if (!ensureAccessibilityPermission(addon)) return null;
|
|
281
1644
|
try {
|
|
@@ -285,7 +1648,7 @@ function getContextJSON() {
|
|
|
285
1648
|
}
|
|
286
1649
|
}
|
|
287
1650
|
function getSelectedTextSmart() {
|
|
288
|
-
if (!
|
|
1651
|
+
if (!IS_MACOS2) return null;
|
|
289
1652
|
const addon = getNativeAddon();
|
|
290
1653
|
if (!ensureAccessibilityPermission(addon)) return null;
|
|
291
1654
|
try {
|
|
@@ -308,10 +1671,36 @@ function setBlockSystemHotkeys(block) {
|
|
|
308
1671
|
0 && (module.exports = {
|
|
309
1672
|
checkKeyboardPermission,
|
|
310
1673
|
createGlobalKeyboardListener,
|
|
1674
|
+
escapeForAppleScript,
|
|
1675
|
+
executeAndParse,
|
|
1676
|
+
executeAppleScript,
|
|
1677
|
+
executeAppleScriptLines,
|
|
1678
|
+
executeMultilineAndParse,
|
|
1679
|
+
getAgentContext,
|
|
1680
|
+
getClipboardContent,
|
|
1681
|
+
getClipboardText,
|
|
311
1682
|
getContextJSON,
|
|
1683
|
+
getDesktopItems,
|
|
1684
|
+
getDesktopPath,
|
|
1685
|
+
getFileMetadata,
|
|
1686
|
+
getFilesMetadata,
|
|
1687
|
+
getFinderContext,
|
|
1688
|
+
getFinderCurrentFolder,
|
|
1689
|
+
getFinderSelection,
|
|
1690
|
+
getFinderWindows,
|
|
312
1691
|
getFocusedInputSelectedText,
|
|
313
1692
|
getFocusedInputValue,
|
|
1693
|
+
getFrontmostApp,
|
|
1694
|
+
getFrontmostFromRunning,
|
|
314
1695
|
getGlobalKeyboardListener,
|
|
1696
|
+
getRecentDocuments,
|
|
1697
|
+
getRecentFiles,
|
|
1698
|
+
getRunningApps,
|
|
315
1699
|
getSelectedTextSmart,
|
|
1700
|
+
getSystemContext,
|
|
1701
|
+
isAppRunning,
|
|
1702
|
+
isOsascriptAvailable,
|
|
1703
|
+
readFileContent,
|
|
1704
|
+
readMultipleFiles,
|
|
316
1705
|
setBlockSystemHotkeys
|
|
317
1706
|
});
|