simen-keyboard-listener 1.1.18 → 1.1.20

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/README.md CHANGED
@@ -145,6 +145,21 @@ interface IGlobalKeyEvent {
145
145
  }
146
146
  ```
147
147
 
148
+ ### Context APIs (macOS & Windows)
149
+
150
+ 这些 API 在 macOS 和 Windows 上都可用:
151
+
152
+ - `getSelectedTextSmart(): string | null` - 获取选中文本(必要时模拟 Cmd+C / Ctrl+C)
153
+ - `getContextJSON(): string | null` - 获取完整上下文(JSON)
154
+ - `getFrontmostAppInfo(): IAppInfo | null` - 获取前台应用信息
155
+ - `getFocusedElementInfo(): IElementInfo | null` - 获取焦点元素信息
156
+ - `getFocusedTextInfo(): ITextInfo | null` - 获取文本信息(选中/输入框等)
157
+ - `getFocusedDOMInfo(): IDOMInfo | null` - 获取浏览器 DOM 信息(仅浏览器应用)
158
+
159
+ **平台差异:**
160
+ - macOS: 使用 Accessibility API,需要辅助功能权限
161
+ - Windows: 使用 UI Automation API,无需特殊权限
162
+
148
163
  ## Supported Keys
149
164
 
150
165
  - **Modifiers**: FN (macOS), SHIFT, CTRL, ALT, META (Cmd/Win)
package/dist/index.d.mts CHANGED
@@ -853,6 +853,47 @@ interface IGlobalKeyEvent {
853
853
  type IGlobalKeyDownMap = Record<string, boolean>;
854
854
  type IGlobalKeyListener = (event: IGlobalKeyEvent, isDown: IGlobalKeyDownMap) => void;
855
855
  type IPermissionLostListener = () => void;
856
+ /**
857
+ * Frontmost app info - lightweight app context
858
+ */
859
+ interface IFrontmostInfo {
860
+ readonly app: {
861
+ readonly name: string;
862
+ readonly bundleId: string;
863
+ readonly pid: number;
864
+ readonly appType: 'browser' | 'wechat' | 'editor' | 'terminal' | 'other';
865
+ };
866
+ readonly window: {
867
+ readonly title: string | null;
868
+ readonly url: string | null;
869
+ };
870
+ }
871
+ /**
872
+ * Unified page context info - the main context API structure
873
+ */
874
+ interface IPageContextInfo {
875
+ readonly app: {
876
+ readonly name: string;
877
+ readonly bundleId: string;
878
+ readonly appType: 'browser' | 'wechat' | 'editor' | 'terminal' | 'other';
879
+ };
880
+ readonly window: {
881
+ readonly title: string | null;
882
+ readonly url: string | null;
883
+ };
884
+ readonly focusedElement: {
885
+ readonly role: string;
886
+ readonly isEditable: boolean;
887
+ readonly value: string | null;
888
+ readonly placeholder: string | null;
889
+ readonly label: string | null;
890
+ };
891
+ readonly selectedText: string | null;
892
+ readonly cursor: {
893
+ readonly position: number | null;
894
+ readonly line: number | null;
895
+ } | null;
896
+ }
856
897
  interface IGlobalKeyboardListener {
857
898
  addListener(listener: IGlobalKeyListener): void;
858
899
  removeListener(listener: IGlobalKeyListener): void;
@@ -882,17 +923,32 @@ declare function createGlobalKeyboardListener(): IGlobalKeyboardListener;
882
923
  * Call this before starting the listener to provide better UX when permission is missing.
883
924
  */
884
925
  declare function checkKeyboardPermission(): boolean;
885
- declare function getFocusedInputValue(): string | null;
886
- declare function getFocusedInputSelectedText(): string | null;
887
926
  /**
888
- * 获取完整上下文信息(JSON 格式)
889
- * 包含:应用信息、焦点元素、选中文本、DOM 信息等
890
- * @returns JSON 字符串或 null
927
+ * Check if the currently focused element is editable
928
+ * @returns true if focused element is editable, false otherwise
929
+ */
930
+ declare function isEditable(): boolean;
931
+ /**
932
+ * Get the value of the currently focused input element
933
+ * @returns input value string or null
934
+ */
935
+ declare function getFocusedValue(): string | null;
936
+ /**
937
+ * Get frontmost app info (lightweight)
938
+ * Includes: app info, window title/url
939
+ * @returns frontmost info or null
940
+ */
941
+ declare function getFrontmostInfo(): IFrontmostInfo | null;
942
+ /**
943
+ * Get unified page context info
944
+ * Includes: app info, window info, focused element, selected text, cursor position
945
+ * @returns page context or null
891
946
  */
892
- declare function getContextJSON(): string | null;
947
+ declare function getPageContext(): IPageContextInfo | null;
893
948
  /**
894
949
  * 智能获取选中文本
895
- * 优先用 Accessibility API,失败则用模拟 Cmd+C(支持微信等)
950
+ * - macOS: 优先用 Accessibility API,失败则用模拟 Cmd+C
951
+ * - Windows: 优先用 UI Automation,失败则用模拟 Ctrl+C
896
952
  * @returns 选中文本或 null
897
953
  */
898
954
  declare function getSelectedTextSmart(): string | null;
@@ -935,4 +991,4 @@ declare function setBlockSystemHotkeys(block: boolean): void;
935
991
  */
936
992
  declare function setBlockedShortcuts(shortcuts: string[]): void;
937
993
 
938
- export { type IAgentContext$1 as IAgentContext, type IAgentContextOptions$1 as IAgentContextOptions, type IClipboardContent$1 as IClipboardContent, type IDesktopItem$1 as IDesktopItem, type IExecuteOptions$1 as IExecuteOptions, type IExecuteResult$1 as IExecuteResult, type IFileContent$1 as IFileContent, type IFileMetadata$1 as IFileMetadata, type IFinderContext, type IFinderItem, type IFinderSelection, type IFinderWindow, type IFinderWindowInfo, type IFinderWindowItem, type IFrontmostApp$1 as IFrontmostApp, type IGlobalKeyDownMap, type IGlobalKeyEvent, type IGlobalKeyListener, type IGlobalKeyState, type IGlobalKeyboardListener, type IPermissionLostListener, type IReadFileOptions$1 as IReadFileOptions, type IRecentFile$1 as IRecentFile, type IRunningApp$1 as IRunningApp, type ISelectedItem$1 as ISelectedItem, type ISystemContext$1 as ISystemContext, checkKeyboardPermission, createGlobalKeyboardListener, escapeForAppleScript, executeAndParse$1 as executeAndParse, executeAppleScript, executeAppleScriptLines, executeMultilineAndParse$1 as executeMultilineAndParse, getAgentContext$1 as getAgentContext, getClipboardContent$1 as getClipboardContent, getClipboardText$1 as getClipboardText, getContextJSON, getDesktopItems, getDesktopPath, getFileMetadata, getFilesMetadata, getFinderContext, getFinderCurrentFolder, getFinderSelection, getFinderWindows, getFocusedInputSelectedText, getFocusedInputValue, getFrontmostApp$1 as getFrontmostApp, getFrontmostFromRunning, getGlobalKeyboardListener, getRecentDocuments, getRecentFiles, getRunningApps, getSelectedTextSmart, getSystemContext$1 as getSystemContext, isAppRunning, isOsascriptAvailable, index as powershell, readFileContent, readMultipleFiles, setBlockSystemHotkeys, setBlockedShortcuts };
994
+ export { type IAgentContext$1 as IAgentContext, type IAgentContextOptions$1 as IAgentContextOptions, type IClipboardContent$1 as IClipboardContent, type IDesktopItem$1 as IDesktopItem, type IExecuteOptions$1 as IExecuteOptions, type IExecuteResult$1 as IExecuteResult, type IFileContent$1 as IFileContent, type IFileMetadata$1 as IFileMetadata, type IFinderContext, type IFinderItem, type IFinderSelection, type IFinderWindow, type IFinderWindowInfo, type IFinderWindowItem, type IFrontmostApp$1 as IFrontmostApp, type IFrontmostInfo, type IGlobalKeyDownMap, type IGlobalKeyEvent, type IGlobalKeyListener, type IGlobalKeyState, type IGlobalKeyboardListener, type IPageContextInfo, type IPermissionLostListener, type IReadFileOptions$1 as IReadFileOptions, type IRecentFile$1 as IRecentFile, type IRunningApp$1 as IRunningApp, type ISelectedItem$1 as ISelectedItem, type ISystemContext$1 as ISystemContext, checkKeyboardPermission, createGlobalKeyboardListener, escapeForAppleScript, executeAndParse$1 as executeAndParse, executeAppleScript, executeAppleScriptLines, executeMultilineAndParse$1 as executeMultilineAndParse, getAgentContext$1 as getAgentContext, getClipboardContent$1 as getClipboardContent, getClipboardText$1 as getClipboardText, getDesktopItems, getDesktopPath, getFileMetadata, getFilesMetadata, getFinderContext, getFinderCurrentFolder, getFinderSelection, getFinderWindows, getFocusedValue, getFrontmostApp$1 as getFrontmostApp, getFrontmostFromRunning, getFrontmostInfo, getGlobalKeyboardListener, getPageContext, getRecentDocuments, getRecentFiles, getRunningApps, getSelectedTextSmart, getSystemContext$1 as getSystemContext, isAppRunning, isEditable, isOsascriptAvailable, index as powershell, readFileContent, readMultipleFiles, setBlockSystemHotkeys, setBlockedShortcuts };
package/dist/index.d.ts CHANGED
@@ -853,6 +853,47 @@ interface IGlobalKeyEvent {
853
853
  type IGlobalKeyDownMap = Record<string, boolean>;
854
854
  type IGlobalKeyListener = (event: IGlobalKeyEvent, isDown: IGlobalKeyDownMap) => void;
855
855
  type IPermissionLostListener = () => void;
856
+ /**
857
+ * Frontmost app info - lightweight app context
858
+ */
859
+ interface IFrontmostInfo {
860
+ readonly app: {
861
+ readonly name: string;
862
+ readonly bundleId: string;
863
+ readonly pid: number;
864
+ readonly appType: 'browser' | 'wechat' | 'editor' | 'terminal' | 'other';
865
+ };
866
+ readonly window: {
867
+ readonly title: string | null;
868
+ readonly url: string | null;
869
+ };
870
+ }
871
+ /**
872
+ * Unified page context info - the main context API structure
873
+ */
874
+ interface IPageContextInfo {
875
+ readonly app: {
876
+ readonly name: string;
877
+ readonly bundleId: string;
878
+ readonly appType: 'browser' | 'wechat' | 'editor' | 'terminal' | 'other';
879
+ };
880
+ readonly window: {
881
+ readonly title: string | null;
882
+ readonly url: string | null;
883
+ };
884
+ readonly focusedElement: {
885
+ readonly role: string;
886
+ readonly isEditable: boolean;
887
+ readonly value: string | null;
888
+ readonly placeholder: string | null;
889
+ readonly label: string | null;
890
+ };
891
+ readonly selectedText: string | null;
892
+ readonly cursor: {
893
+ readonly position: number | null;
894
+ readonly line: number | null;
895
+ } | null;
896
+ }
856
897
  interface IGlobalKeyboardListener {
857
898
  addListener(listener: IGlobalKeyListener): void;
858
899
  removeListener(listener: IGlobalKeyListener): void;
@@ -882,17 +923,32 @@ declare function createGlobalKeyboardListener(): IGlobalKeyboardListener;
882
923
  * Call this before starting the listener to provide better UX when permission is missing.
883
924
  */
884
925
  declare function checkKeyboardPermission(): boolean;
885
- declare function getFocusedInputValue(): string | null;
886
- declare function getFocusedInputSelectedText(): string | null;
887
926
  /**
888
- * 获取完整上下文信息(JSON 格式)
889
- * 包含:应用信息、焦点元素、选中文本、DOM 信息等
890
- * @returns JSON 字符串或 null
927
+ * Check if the currently focused element is editable
928
+ * @returns true if focused element is editable, false otherwise
929
+ */
930
+ declare function isEditable(): boolean;
931
+ /**
932
+ * Get the value of the currently focused input element
933
+ * @returns input value string or null
934
+ */
935
+ declare function getFocusedValue(): string | null;
936
+ /**
937
+ * Get frontmost app info (lightweight)
938
+ * Includes: app info, window title/url
939
+ * @returns frontmost info or null
940
+ */
941
+ declare function getFrontmostInfo(): IFrontmostInfo | null;
942
+ /**
943
+ * Get unified page context info
944
+ * Includes: app info, window info, focused element, selected text, cursor position
945
+ * @returns page context or null
891
946
  */
892
- declare function getContextJSON(): string | null;
947
+ declare function getPageContext(): IPageContextInfo | null;
893
948
  /**
894
949
  * 智能获取选中文本
895
- * 优先用 Accessibility API,失败则用模拟 Cmd+C(支持微信等)
950
+ * - macOS: 优先用 Accessibility API,失败则用模拟 Cmd+C
951
+ * - Windows: 优先用 UI Automation,失败则用模拟 Ctrl+C
896
952
  * @returns 选中文本或 null
897
953
  */
898
954
  declare function getSelectedTextSmart(): string | null;
@@ -935,4 +991,4 @@ declare function setBlockSystemHotkeys(block: boolean): void;
935
991
  */
936
992
  declare function setBlockedShortcuts(shortcuts: string[]): void;
937
993
 
938
- export { type IAgentContext$1 as IAgentContext, type IAgentContextOptions$1 as IAgentContextOptions, type IClipboardContent$1 as IClipboardContent, type IDesktopItem$1 as IDesktopItem, type IExecuteOptions$1 as IExecuteOptions, type IExecuteResult$1 as IExecuteResult, type IFileContent$1 as IFileContent, type IFileMetadata$1 as IFileMetadata, type IFinderContext, type IFinderItem, type IFinderSelection, type IFinderWindow, type IFinderWindowInfo, type IFinderWindowItem, type IFrontmostApp$1 as IFrontmostApp, type IGlobalKeyDownMap, type IGlobalKeyEvent, type IGlobalKeyListener, type IGlobalKeyState, type IGlobalKeyboardListener, type IPermissionLostListener, type IReadFileOptions$1 as IReadFileOptions, type IRecentFile$1 as IRecentFile, type IRunningApp$1 as IRunningApp, type ISelectedItem$1 as ISelectedItem, type ISystemContext$1 as ISystemContext, checkKeyboardPermission, createGlobalKeyboardListener, escapeForAppleScript, executeAndParse$1 as executeAndParse, executeAppleScript, executeAppleScriptLines, executeMultilineAndParse$1 as executeMultilineAndParse, getAgentContext$1 as getAgentContext, getClipboardContent$1 as getClipboardContent, getClipboardText$1 as getClipboardText, getContextJSON, getDesktopItems, getDesktopPath, getFileMetadata, getFilesMetadata, getFinderContext, getFinderCurrentFolder, getFinderSelection, getFinderWindows, getFocusedInputSelectedText, getFocusedInputValue, getFrontmostApp$1 as getFrontmostApp, getFrontmostFromRunning, getGlobalKeyboardListener, getRecentDocuments, getRecentFiles, getRunningApps, getSelectedTextSmart, getSystemContext$1 as getSystemContext, isAppRunning, isOsascriptAvailable, index as powershell, readFileContent, readMultipleFiles, setBlockSystemHotkeys, setBlockedShortcuts };
994
+ export { type IAgentContext$1 as IAgentContext, type IAgentContextOptions$1 as IAgentContextOptions, type IClipboardContent$1 as IClipboardContent, type IDesktopItem$1 as IDesktopItem, type IExecuteOptions$1 as IExecuteOptions, type IExecuteResult$1 as IExecuteResult, type IFileContent$1 as IFileContent, type IFileMetadata$1 as IFileMetadata, type IFinderContext, type IFinderItem, type IFinderSelection, type IFinderWindow, type IFinderWindowInfo, type IFinderWindowItem, type IFrontmostApp$1 as IFrontmostApp, type IFrontmostInfo, type IGlobalKeyDownMap, type IGlobalKeyEvent, type IGlobalKeyListener, type IGlobalKeyState, type IGlobalKeyboardListener, type IPageContextInfo, type IPermissionLostListener, type IReadFileOptions$1 as IReadFileOptions, type IRecentFile$1 as IRecentFile, type IRunningApp$1 as IRunningApp, type ISelectedItem$1 as ISelectedItem, type ISystemContext$1 as ISystemContext, checkKeyboardPermission, createGlobalKeyboardListener, escapeForAppleScript, executeAndParse$1 as executeAndParse, executeAppleScript, executeAppleScriptLines, executeMultilineAndParse$1 as executeMultilineAndParse, getAgentContext$1 as getAgentContext, getClipboardContent$1 as getClipboardContent, getClipboardText$1 as getClipboardText, getDesktopItems, getDesktopPath, getFileMetadata, getFilesMetadata, getFinderContext, getFinderCurrentFolder, getFinderSelection, getFinderWindows, getFocusedValue, getFrontmostApp$1 as getFrontmostApp, getFrontmostFromRunning, getFrontmostInfo, getGlobalKeyboardListener, getPageContext, getRecentDocuments, getRecentFiles, getRunningApps, getSelectedTextSmart, getSystemContext$1 as getSystemContext, isAppRunning, isEditable, isOsascriptAvailable, index as powershell, readFileContent, readMultipleFiles, setBlockSystemHotkeys, setBlockedShortcuts };
package/dist/index.js CHANGED
@@ -40,7 +40,6 @@ __export(index_exports, {
40
40
  getAgentContext: () => getAgentContext,
41
41
  getClipboardContent: () => getClipboardContent,
42
42
  getClipboardText: () => getClipboardText,
43
- getContextJSON: () => getContextJSON,
44
43
  getDesktopItems: () => getDesktopItems,
45
44
  getDesktopPath: () => getDesktopPath,
46
45
  getFileMetadata: () => getFileMetadata,
@@ -49,17 +48,19 @@ __export(index_exports, {
49
48
  getFinderCurrentFolder: () => getFinderCurrentFolder,
50
49
  getFinderSelection: () => getFinderSelection,
51
50
  getFinderWindows: () => getFinderWindows,
52
- getFocusedInputSelectedText: () => getFocusedInputSelectedText,
53
- getFocusedInputValue: () => getFocusedInputValue,
51
+ getFocusedValue: () => getFocusedValue,
54
52
  getFrontmostApp: () => getFrontmostApp,
55
53
  getFrontmostFromRunning: () => getFrontmostFromRunning,
54
+ getFrontmostInfo: () => getFrontmostInfo,
56
55
  getGlobalKeyboardListener: () => getGlobalKeyboardListener,
56
+ getPageContext: () => getPageContext,
57
57
  getRecentDocuments: () => getRecentDocuments,
58
58
  getRecentFiles: () => getRecentFiles,
59
59
  getRunningApps: () => getRunningApps,
60
60
  getSelectedTextSmart: () => getSelectedTextSmart,
61
61
  getSystemContext: () => getSystemContext,
62
62
  isAppRunning: () => isAppRunning,
63
+ isEditable: () => isEditable,
63
64
  isOsascriptAvailable: () => isOsascriptAvailable,
64
65
  powershell: () => powershell_exports,
65
66
  readFileContent: () => readFileContent,
@@ -2289,6 +2290,14 @@ async function getSystemContext2(options) {
2289
2290
 
2290
2291
  // src/index.ts
2291
2292
  var import_meta = {};
2293
+ function tryParseJSON(json) {
2294
+ if (!json) return null;
2295
+ try {
2296
+ return JSON.parse(json);
2297
+ } catch {
2298
+ return null;
2299
+ }
2300
+ }
2292
2301
  var IS_MACOS2 = process.platform === "darwin";
2293
2302
  var IS_WINDOWS2 = process.platform === "win32";
2294
2303
  var PLATFORM_PACKAGES = {
@@ -2326,8 +2335,7 @@ function getNativeAddon() {
2326
2335
  try {
2327
2336
  const candidate = localRequire(packageName);
2328
2337
  const hasCoreFunctions = candidate && typeof candidate.start === "function" && typeof candidate.stop === "function" && typeof candidate.isRunning === "function" && typeof candidate.checkPermission === "function";
2329
- const hasMacOSFunctions = IS_MACOS2 ? typeof candidate.getFocusedInputValue === "function" && typeof candidate.getFocusedInputSelectedText === "function" : true;
2330
- if (hasCoreFunctions && hasMacOSFunctions) {
2338
+ if (hasCoreFunctions) {
2331
2339
  nativeAddon = candidate;
2332
2340
  return nativeAddon;
2333
2341
  }
@@ -2489,48 +2497,50 @@ function ensureAccessibilityPermission(addon) {
2489
2497
  openMacAccessibilitySettings();
2490
2498
  return false;
2491
2499
  }
2492
- function getFocusedInputValue() {
2493
- if (!IS_MACOS2) {
2494
- return null;
2495
- }
2500
+ function isEditable() {
2501
+ if (!IS_MACOS2 && !IS_WINDOWS2) return false;
2496
2502
  const addon = getNativeAddon();
2497
- if (!ensureAccessibilityPermission(addon)) {
2498
- return null;
2499
- }
2503
+ if (IS_MACOS2 && !ensureAccessibilityPermission(addon)) return false;
2500
2504
  try {
2501
- return addon.getFocusedInputValue();
2505
+ return addon.isEditable?.() ?? false;
2502
2506
  } catch {
2503
- return null;
2507
+ return false;
2504
2508
  }
2505
2509
  }
2506
- function getFocusedInputSelectedText() {
2507
- if (!IS_MACOS2) {
2508
- return null;
2509
- }
2510
+ function getFocusedValue() {
2511
+ if (!IS_MACOS2 && !IS_WINDOWS2) return null;
2510
2512
  const addon = getNativeAddon();
2511
- if (!ensureAccessibilityPermission(addon)) {
2513
+ if (IS_MACOS2 && !ensureAccessibilityPermission(addon)) return null;
2514
+ try {
2515
+ return addon.getFocusedValue?.() ?? null;
2516
+ } catch {
2512
2517
  return null;
2513
2518
  }
2519
+ }
2520
+ function getFrontmostInfo() {
2521
+ if (!IS_MACOS2 && !IS_WINDOWS2) return null;
2522
+ const addon = getNativeAddon();
2523
+ if (IS_MACOS2 && !ensureAccessibilityPermission(addon)) return null;
2514
2524
  try {
2515
- return addon.getFocusedInputSelectedText();
2525
+ return tryParseJSON(addon.getFrontmostInfoJSON?.() ?? null);
2516
2526
  } catch {
2517
2527
  return null;
2518
2528
  }
2519
2529
  }
2520
- function getContextJSON() {
2521
- if (!IS_MACOS2) return null;
2530
+ function getPageContext() {
2531
+ if (!IS_MACOS2 && !IS_WINDOWS2) return null;
2522
2532
  const addon = getNativeAddon();
2523
- if (!ensureAccessibilityPermission(addon)) return null;
2533
+ if (IS_MACOS2 && !ensureAccessibilityPermission(addon)) return null;
2524
2534
  try {
2525
- return addon.getContextJSON?.() ?? null;
2535
+ return tryParseJSON(addon.getPageContextJSON?.() ?? null);
2526
2536
  } catch {
2527
2537
  return null;
2528
2538
  }
2529
2539
  }
2530
2540
  function getSelectedTextSmart() {
2531
- if (!IS_MACOS2) return null;
2541
+ if (!IS_MACOS2 && !IS_WINDOWS2) return null;
2532
2542
  const addon = getNativeAddon();
2533
- if (!ensureAccessibilityPermission(addon)) return null;
2543
+ if (IS_MACOS2 && !ensureAccessibilityPermission(addon)) return null;
2534
2544
  try {
2535
2545
  return addon.getSelectedTextSmart?.() ?? null;
2536
2546
  } catch {
@@ -2569,7 +2579,6 @@ function setBlockedShortcuts(shortcuts) {
2569
2579
  getAgentContext,
2570
2580
  getClipboardContent,
2571
2581
  getClipboardText,
2572
- getContextJSON,
2573
2582
  getDesktopItems,
2574
2583
  getDesktopPath,
2575
2584
  getFileMetadata,
@@ -2578,17 +2587,19 @@ function setBlockedShortcuts(shortcuts) {
2578
2587
  getFinderCurrentFolder,
2579
2588
  getFinderSelection,
2580
2589
  getFinderWindows,
2581
- getFocusedInputSelectedText,
2582
- getFocusedInputValue,
2590
+ getFocusedValue,
2583
2591
  getFrontmostApp,
2584
2592
  getFrontmostFromRunning,
2593
+ getFrontmostInfo,
2585
2594
  getGlobalKeyboardListener,
2595
+ getPageContext,
2586
2596
  getRecentDocuments,
2587
2597
  getRecentFiles,
2588
2598
  getRunningApps,
2589
2599
  getSelectedTextSmart,
2590
2600
  getSystemContext,
2591
2601
  isAppRunning,
2602
+ isEditable,
2592
2603
  isOsascriptAvailable,
2593
2604
  powershell,
2594
2605
  readFileContent,
package/dist/index.mjs CHANGED
@@ -2231,6 +2231,14 @@ async function getSystemContext2(options) {
2231
2231
  }
2232
2232
 
2233
2233
  // src/index.ts
2234
+ function tryParseJSON(json) {
2235
+ if (!json) return null;
2236
+ try {
2237
+ return JSON.parse(json);
2238
+ } catch {
2239
+ return null;
2240
+ }
2241
+ }
2234
2242
  var IS_MACOS2 = process.platform === "darwin";
2235
2243
  var IS_WINDOWS2 = process.platform === "win32";
2236
2244
  var PLATFORM_PACKAGES = {
@@ -2268,8 +2276,7 @@ function getNativeAddon() {
2268
2276
  try {
2269
2277
  const candidate = localRequire(packageName);
2270
2278
  const hasCoreFunctions = candidate && typeof candidate.start === "function" && typeof candidate.stop === "function" && typeof candidate.isRunning === "function" && typeof candidate.checkPermission === "function";
2271
- const hasMacOSFunctions = IS_MACOS2 ? typeof candidate.getFocusedInputValue === "function" && typeof candidate.getFocusedInputSelectedText === "function" : true;
2272
- if (hasCoreFunctions && hasMacOSFunctions) {
2279
+ if (hasCoreFunctions) {
2273
2280
  nativeAddon = candidate;
2274
2281
  return nativeAddon;
2275
2282
  }
@@ -2431,48 +2438,50 @@ function ensureAccessibilityPermission(addon) {
2431
2438
  openMacAccessibilitySettings();
2432
2439
  return false;
2433
2440
  }
2434
- function getFocusedInputValue() {
2435
- if (!IS_MACOS2) {
2436
- return null;
2437
- }
2441
+ function isEditable() {
2442
+ if (!IS_MACOS2 && !IS_WINDOWS2) return false;
2438
2443
  const addon = getNativeAddon();
2439
- if (!ensureAccessibilityPermission(addon)) {
2440
- return null;
2441
- }
2444
+ if (IS_MACOS2 && !ensureAccessibilityPermission(addon)) return false;
2442
2445
  try {
2443
- return addon.getFocusedInputValue();
2446
+ return addon.isEditable?.() ?? false;
2444
2447
  } catch {
2445
- return null;
2448
+ return false;
2446
2449
  }
2447
2450
  }
2448
- function getFocusedInputSelectedText() {
2449
- if (!IS_MACOS2) {
2450
- return null;
2451
- }
2451
+ function getFocusedValue() {
2452
+ if (!IS_MACOS2 && !IS_WINDOWS2) return null;
2452
2453
  const addon = getNativeAddon();
2453
- if (!ensureAccessibilityPermission(addon)) {
2454
+ if (IS_MACOS2 && !ensureAccessibilityPermission(addon)) return null;
2455
+ try {
2456
+ return addon.getFocusedValue?.() ?? null;
2457
+ } catch {
2454
2458
  return null;
2455
2459
  }
2460
+ }
2461
+ function getFrontmostInfo() {
2462
+ if (!IS_MACOS2 && !IS_WINDOWS2) return null;
2463
+ const addon = getNativeAddon();
2464
+ if (IS_MACOS2 && !ensureAccessibilityPermission(addon)) return null;
2456
2465
  try {
2457
- return addon.getFocusedInputSelectedText();
2466
+ return tryParseJSON(addon.getFrontmostInfoJSON?.() ?? null);
2458
2467
  } catch {
2459
2468
  return null;
2460
2469
  }
2461
2470
  }
2462
- function getContextJSON() {
2463
- if (!IS_MACOS2) return null;
2471
+ function getPageContext() {
2472
+ if (!IS_MACOS2 && !IS_WINDOWS2) return null;
2464
2473
  const addon = getNativeAddon();
2465
- if (!ensureAccessibilityPermission(addon)) return null;
2474
+ if (IS_MACOS2 && !ensureAccessibilityPermission(addon)) return null;
2466
2475
  try {
2467
- return addon.getContextJSON?.() ?? null;
2476
+ return tryParseJSON(addon.getPageContextJSON?.() ?? null);
2468
2477
  } catch {
2469
2478
  return null;
2470
2479
  }
2471
2480
  }
2472
2481
  function getSelectedTextSmart() {
2473
- if (!IS_MACOS2) return null;
2482
+ if (!IS_MACOS2 && !IS_WINDOWS2) return null;
2474
2483
  const addon = getNativeAddon();
2475
- if (!ensureAccessibilityPermission(addon)) return null;
2484
+ if (IS_MACOS2 && !ensureAccessibilityPermission(addon)) return null;
2476
2485
  try {
2477
2486
  return addon.getSelectedTextSmart?.() ?? null;
2478
2487
  } catch {
@@ -2510,7 +2519,6 @@ export {
2510
2519
  getAgentContext,
2511
2520
  getClipboardContent,
2512
2521
  getClipboardText,
2513
- getContextJSON,
2514
2522
  getDesktopItems,
2515
2523
  getDesktopPath,
2516
2524
  getFileMetadata,
@@ -2519,17 +2527,19 @@ export {
2519
2527
  getFinderCurrentFolder,
2520
2528
  getFinderSelection,
2521
2529
  getFinderWindows,
2522
- getFocusedInputSelectedText,
2523
- getFocusedInputValue,
2530
+ getFocusedValue,
2524
2531
  getFrontmostApp,
2525
2532
  getFrontmostFromRunning,
2533
+ getFrontmostInfo,
2526
2534
  getGlobalKeyboardListener,
2535
+ getPageContext,
2527
2536
  getRecentDocuments,
2528
2537
  getRecentFiles,
2529
2538
  getRunningApps,
2530
2539
  getSelectedTextSmart,
2531
2540
  getSystemContext,
2532
2541
  isAppRunning,
2542
+ isEditable,
2533
2543
  isOsascriptAvailable,
2534
2544
  powershell_exports as powershell,
2535
2545
  readFileContent,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "simen-keyboard-listener",
3
- "version": "1.1.18",
3
+ "version": "1.1.20",
4
4
  "description": "Native global keyboard listener for macOS and Windows",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -16,7 +16,7 @@
16
16
  "dist"
17
17
  ],
18
18
  "scripts": {
19
- "build:swift": "cd src/native && swiftc -O -parse-as-library -c ContextHelper.swift -o ContextHelper.o",
19
+ "build:swift": "cd src/native && MACOSX_DEPLOYMENT_TARGET=11.0 swiftc -O -parse-as-library -c ContextHelper.swift -o ContextHelper.o",
20
20
  "build:native": "npm run build:swift && node-gyp rebuild --directory=src/native",
21
21
  "build:ts": "tsup src/index.ts --format cjs,esm --dts --clean",
22
22
  "build": "npm run build:native && npm run build:ts",
@@ -49,8 +49,8 @@
49
49
  "node-addon-api": "^8.0.0"
50
50
  },
51
51
  "optionalDependencies": {
52
- "@simen-keyboard-listener/darwin-arm64": "1.1.18",
53
- "@simen-keyboard-listener/win32-x64": "1.1.18"
52
+ "@simen-keyboard-listener/darwin-arm64": "1.1.20",
53
+ "@simen-keyboard-listener/win32-x64": "1.1.20"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@types/node": "^20.0.0",