@linxiraos/pi-natives 1.3.0 → 1.3.2

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.
@@ -4,6 +4,7 @@ const REQUIRED_METHODS = [
4
4
  "captureRegion",
5
5
  "cancel",
6
6
  "retire",
7
+ "setRunDeadline",
7
8
  "observe",
8
9
  "listApplications",
9
10
  "openApplication",
@@ -15,14 +16,21 @@ const REQUIRED_METHODS = [
15
16
  "releaseControl",
16
17
  "controlState",
17
18
  "bringToCurrentSpace",
19
+ "axSelectText",
18
20
  "holdDisplayUntilReleased",
19
21
  "releaseDisplayAwake",
20
22
  ];
21
23
 
24
+ /** Getters the computer worker reads; without `escapeStops` it would read every run as stopped by the user's Escape. */
25
+ const REQUIRED_GETTERS = ["escapeStops"];
26
+
22
27
  /** Require the current desktop ABI; partial legacy emulation cannot preserve input ownership. */
23
28
  export function adaptDesktopSession(NativeDesktopSession) {
24
29
  const prototype = NativeDesktopSession?.prototype;
25
- const missing = REQUIRED_METHODS.filter(method => typeof prototype?.[method] !== "function");
30
+ const missing = [
31
+ ...REQUIRED_METHODS.filter(method => typeof prototype?.[method] !== "function"),
32
+ ...REQUIRED_GETTERS.filter(getter => !prototype || !(getter in prototype)),
33
+ ];
26
34
  if (missing.length === 0) {
27
35
  return NativeDesktopSession;
28
36
  }
@@ -2,3 +2,12 @@ import type { DesktopSession, DesktopSessionOptions } from "./index.js";
2
2
 
3
3
  /** Construct a desktop session, loading the native addon on first use. */
4
4
  export declare function createDesktopSession(options: DesktopSessionOptions): DesktopSession;
5
+
6
+ /** Physical-Escape stops counted under `key`, loading the native addon on first use. */
7
+ export declare function desktopEscapeStops(key: string): number;
8
+
9
+ /** Drop the stop count kept under `key`. */
10
+ export declare function forgetDesktopEscapeStops(key: string): void;
11
+
12
+ /** Invalidate this process's event taps before it exits (see the native doc). */
13
+ export declare function closeDesktopEventTaps(): void;
package/native/desktop.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { adaptDesktopSession } from "./desktop-adapter.js";
2
- import { loadNative } from "./loader-state.js";
2
+ import { loadNative, missingNativeExport } from "./loader-state.js";
3
3
 
4
4
  let DesktopSession;
5
5
 
@@ -11,3 +11,22 @@ export function createDesktopSession(options) {
11
11
  DesktopSession ??= adaptDesktopSession(loadNative().DesktopSession);
12
12
  return new DesktopSession(options);
13
13
  }
14
+
15
+ // A stale workspace addon lacks the Escape exports; fall back to the stub
16
+ // `native/index.js` exports in their place, which names the rebuild.
17
+
18
+ /** Physical-Escape stops counted under `key`, loading the native addon on first use. */
19
+ export function desktopEscapeStops(key) {
20
+ return (loadNative().desktopEscapeStops ?? missingNativeExport("desktopEscapeStops"))(key);
21
+ }
22
+
23
+ /** Drop the stop count kept under `key`. */
24
+ export function forgetDesktopEscapeStops(key) {
25
+ (loadNative().forgetDesktopEscapeStops ?? missingNativeExport("forgetDesktopEscapeStops"))(key);
26
+ }
27
+
28
+ /** Invalidate this process's event taps before it exits (see the native doc). A stale
29
+ * workspace addon without the export holds no such taps. */
30
+ export function closeDesktopEventTaps() {
31
+ loadNative().closeDesktopEventTaps?.();
32
+ }
package/native/index.d.ts CHANGED
@@ -56,10 +56,16 @@ export declare class DesktopSession {
56
56
  * outside a turn keeps its grace. An agent calls this when its turn ends.
57
57
  */
58
58
  releaseDisplayAwake(): void
59
+ /**
60
+ * How many times the user's physical Escape has stopped takeover input in
61
+ * this session, or under its `escapeStopKey`. Host cancels, retirement and
62
+ * release never count, so a rise tells the host the user stopped the work.
63
+ */
64
+ get escapeStops(): number
59
65
  listDisplays(): Promise<Array<DesktopDisplay>>
60
66
  listWindows(): Promise<Array<DesktopWindow>>
61
67
  listApplications(options?: ApplicationQuery | undefined | null): Promise<Array<Application>>
62
- openApplication(id: string, options?: ApplicationOpenOptions | undefined | null): Promise<Application>
68
+ openApplication(id: string, options?: ApplicationOpenOptions | undefined | null): Promise<OpenedApplication>
63
69
  /**
64
70
  * Capture and accessibility share one serialized request. Neither a failed
65
71
  * snapshot nor an abandoned reply replaces the last delivered input frame.
@@ -68,8 +74,8 @@ export declare class DesktopSession {
68
74
  menuItems(target: string, path?: Array<string> | undefined | null): Promise<Array<DesktopMenuItem>>
69
75
  menuSelect(target: string, path: Array<string>): Promise<undefined>
70
76
  bringToCurrentSpace(windowId: string): Promise<undefined>
71
- holdKeys(target: string, keys: Array<string>, options: HoldOptions): Promise<undefined>
72
- holdMouse(target: string, x: number, y: number, options: HoldOptions): Promise<undefined>
77
+ holdKeys(target: string, keys: Array<string>, options: HoldOptions): Promise<DesktopFocusReturn | undefined | null>
78
+ holdMouse(target: string, x: number, y: number, options: HoldOptions): Promise<DesktopFocusReturn | undefined | null>
73
79
  /**
74
80
  * Native ownership only. Human approval is required by the host before
75
81
  * calling this method.
@@ -79,18 +85,24 @@ export declare class DesktopSession {
79
85
  controlState(): DesktopControlState
80
86
  /** Retire queued work from a completed helper without revoking task control. */
81
87
  retire(): void
88
+ /**
89
+ * Sets when the current run ends, `remaining_ms` from now; each run sets
90
+ * it before its first call. On macOS, input waiting for the user to pause
91
+ * in its app gives up shortly before it.
92
+ */
93
+ setRunDeadline(remainingMs: number): void
82
94
  capture(target: string, caps?: CaptureCaps | undefined | null): Promise<DesktopCapture>
83
95
  /**
84
96
  * Capture a fresh native-detail region without replacing the full input
85
97
  * coordinate frame.
86
98
  */
87
99
  captureRegion(target: string, region: CaptureRegion, caps?: CaptureCaps | undefined | null): Promise<DesktopCapture>
88
- click(target: string, x: number, y: number, opts?: PointerOptions | undefined | null): Promise<undefined>
89
- moveMouse(target: string, x: number, y: number, opts?: PointerOptions | undefined | null): Promise<undefined>
90
- drag(target: string, path: Array<DesktopPoint>, opts?: PointerOptions | undefined | null): Promise<undefined>
91
- scroll(target: string, x: number, y: number, dx: number, dy: number, opts?: PointerOptions | undefined | null): Promise<undefined>
92
- typeText(target: string, text: string, opts?: PointerOptions | undefined | null): Promise<undefined>
93
- keyChord(target: string, keys: Array<string>, opts?: PointerOptions | undefined | null): Promise<undefined>
100
+ click(target: string, x: number, y: number, opts?: PointerOptions | undefined | null): Promise<DesktopFocusReturn | undefined | null>
101
+ moveMouse(target: string, x: number, y: number, opts?: PointerOptions | undefined | null): Promise<DesktopFocusReturn | undefined | null>
102
+ drag(target: string, path: Array<DesktopPoint>, opts?: PointerOptions | undefined | null): Promise<DesktopFocusReturn | undefined | null>
103
+ scroll(target: string, x: number, y: number, dx: number, dy: number, opts?: PointerOptions | undefined | null): Promise<DesktopFocusReturn | undefined | null>
104
+ typeText(target: string, text: string, opts?: PointerOptions | undefined | null): Promise<DesktopFocusReturn | undefined | null>
105
+ keyChord(target: string, keys: Array<string>, opts?: PointerOptions | undefined | null): Promise<DesktopFocusReturn | undefined | null>
94
106
  raiseWindow(windowId: string): Promise<undefined>
95
107
  axSnapshot(target: string, opts?: AxSnapshotOptions | undefined | null): Promise<AxSnapshot>
96
108
  axQuery(target: string, query: AxQuery): Promise<Array<AxNode>>
@@ -104,10 +116,26 @@ export declare class DesktopSession {
104
116
  axAttributes(reference: string): Promise<Array<[string, string]>>
105
117
  axChildren(reference: string): Promise<Array<AxNode>>
106
118
  axParent(reference: string): Promise<AxNode | undefined | null>
107
- axPerform(reference: string, action: string): Promise<undefined>
119
+ /**
120
+ * Performs `action` on the element; with `menu`, chooses that item path
121
+ * in the menu the action opens, which closes it.
122
+ */
123
+ axPerform(reference: string, action: string, menu?: Array<string> | undefined | null): Promise<undefined>
108
124
  axSetValue(reference: string, value: string): Promise<undefined>
125
+ /**
126
+ * Selects `text` in the element's value by accessibility, or places a
127
+ * caret at its start or end, without focus change or keystrokes.
128
+ */
129
+ axSelectText(reference: string, text: string, opts?: AxSelectTextOptions | undefined | null): Promise<AxTextSelection>
109
130
  axFocus(reference: string): Promise<undefined>
110
- axClick(reference: string, opts?: PointerOptions | undefined | null): Promise<undefined>
131
+ axClick(reference: string, opts?: PointerOptions | undefined | null): Promise<DesktopFocusReturn | undefined | null>
132
+ /**
133
+ * Types `text` into the element: native text fields take it by AX
134
+ * insertion, other elements as keystrokes once they hold keyboard focus.
135
+ */
136
+ axType(reference: string, text: string, opts?: PointerOptions | undefined | null): Promise<DesktopFocusReturn | undefined | null>
137
+ /** Presses a key chord in the element once it holds keyboard focus. */
138
+ axKeyChord(reference: string, keys: Array<string>, opts?: PointerOptions | undefined | null): Promise<DesktopFocusReturn | undefined | null>
111
139
  /**
112
140
  * Immediately cancel operations submitted before this call. Later
113
141
  * operations may proceed.
@@ -1184,6 +1212,16 @@ export interface AxQuery {
1184
1212
  limit?: number
1185
1213
  }
1186
1214
 
1215
+ /** Where `axSelectText` looks for its text and what it selects there. */
1216
+ export interface AxSelectTextOptions {
1217
+ /** Text that must directly precede the match. */
1218
+ prefix?: string
1219
+ /** Text that must directly follow the match. */
1220
+ suffix?: string
1221
+ /** `text` (default) selects the match; `start` and `end` place a caret. */
1222
+ select?: string
1223
+ }
1224
+
1187
1225
  export interface AxSnapshot {
1188
1226
  text: string
1189
1227
  nodeCount: number
@@ -1196,6 +1234,19 @@ export interface AxSnapshotOptions {
1196
1234
  all?: boolean
1197
1235
  }
1198
1236
 
1237
+ /** The selection read back after `axSelectText`, in UTF-16 code units. */
1238
+ export interface AxTextSelection {
1239
+ start: number
1240
+ length: number
1241
+ /** The selected text, empty for a caret. */
1242
+ text: string
1243
+ /**
1244
+ * Whether the element is focused in its app: typing and AX insertion
1245
+ * act on the focused element.
1246
+ */
1247
+ focused: boolean
1248
+ }
1249
+
1199
1250
  export interface BlockParseOptions {
1200
1251
  /** Source code to parse. */
1201
1252
  code: string
@@ -1253,6 +1304,15 @@ export interface ClipboardImage {
1253
1304
  mimeType: string
1254
1305
  }
1255
1306
 
1307
+ /**
1308
+ * Invalidates this process's event taps; for a host about to
1309
+ * exit, after which no desktop session here sees the user's input again. A
1310
+ * macOS tap that dies with its process while the user types makes
1311
+ * `WindowServer` deliver their key again; Bun's `process.exit` runs no native
1312
+ * exit hook, so the host calls this from its exit handler.
1313
+ */
1314
+ export declare function closeDesktopEventTaps(): void
1315
+
1256
1316
  /** A context line (before or after a match). */
1257
1317
  export interface ContextLine {
1258
1318
  /** 1-indexed line number in the source file. */
@@ -1332,8 +1392,10 @@ export interface DesktopCapabilities {
1332
1392
  heldInput: boolean
1333
1393
  spaces: boolean
1334
1394
  /**
1335
- * Native global Escape cancellation while input/control ownership is held.
1336
- * Wayland requires the host interrupt action instead.
1395
+ * Native global Escape cancellation of takeover input (`takeover: true`,
1396
+ * held control, desktop/display-level input, raises, activating launches).
1397
+ * Without held control, background window input never watches the user's
1398
+ * keys; it and Wayland stop only through the host interrupt.
1337
1399
  */
1338
1400
  globalEscape: boolean
1339
1401
  capturePermission: string
@@ -1406,6 +1468,20 @@ export interface DesktopDisplay {
1406
1468
  isPrimary: boolean
1407
1469
  }
1408
1470
 
1471
+ /**
1472
+ * Where focus ended after a takeover input call, as `WindowServer` reports
1473
+ * it. Input calls resolve to it on macOS when they took over; other
1474
+ * backends and background delivery resolve to `null`.
1475
+ */
1476
+ export interface DesktopFocusReturn {
1477
+ /** Whether the takeover handed focus back to the app front before it. */
1478
+ handedBack: boolean
1479
+ /** The process front before the takeover. */
1480
+ previousPid?: number
1481
+ /** The process front once the takeover ended; absent when unreadable. */
1482
+ frontPid?: number
1483
+ }
1484
+
1409
1485
  /**
1410
1486
  * One immediate child of a native application menu. Paths contain the actual
1411
1487
  * native labels, including ellipses; selection accepts normalized labels.
@@ -1438,8 +1514,19 @@ export interface DesktopScreenState {
1438
1514
  displayAsleep: boolean
1439
1515
  }
1440
1516
 
1517
+ /**
1518
+ * Physical-Escape stops counted under `key` by every desktop session created
1519
+ * with it, including closed ones, until the key is forgotten.
1520
+ */
1521
+ export declare function desktopEscapeStops(key: string): number
1522
+
1441
1523
  export interface DesktopSessionOptions {
1442
1524
  display?: string
1525
+ /**
1526
+ * Sessions created with the same key share one physical-Escape stop
1527
+ * count, which `desktopEscapeStops` reads after they close.
1528
+ */
1529
+ escapeStopKey?: string
1443
1530
  }
1444
1531
 
1445
1532
  /** One capturable top-level window in global logical desktop coordinates. */
@@ -1902,6 +1989,9 @@ export declare enum FileType {
1902
1989
  Symlink = 3
1903
1990
  }
1904
1991
 
1992
+ /** Drops the stop count kept under `key` once no session will use it again. */
1993
+ export declare function forgetDesktopEscapeStops(key: string): void
1994
+
1905
1995
  /** Fuzzy file path search for autocomplete. */
1906
1996
  export declare function fuzzyFind(options: FuzzyFindOptions): Promise<FuzzyFindResult>
1907
1997
 
@@ -2256,6 +2346,16 @@ export interface HoldOptions {
2256
2346
  button?: string
2257
2347
  keys?: Array<string>
2258
2348
  takeover?: boolean
2349
+ /**
2350
+ * With `takeover`, hand focus back to the user's app even after their
2351
+ * input during the hold; see `PointerOptions.returnFocus`.
2352
+ */
2353
+ returnFocus?: boolean
2354
+ /**
2355
+ * Refuse a background left hold that starts on a control that opens a
2356
+ * menu; see `PointerOptions.refuseMenu`.
2357
+ */
2358
+ refuseMenu?: boolean
2259
2359
  }
2260
2360
 
2261
2361
  /**
@@ -2744,6 +2844,20 @@ export declare function notebookToEditableText(json: string, displayPath: string
2744
2844
  /** Check syntax through the shared parse cache without constructing a summary. */
2745
2845
  export declare function parseCodeStatus(options: ParseStatusOptions): ParseStatus
2746
2846
 
2847
+ /**
2848
+ * An opened application: its [`Application`] fields and the window it
2849
+ * shows. On macOS `window` is its frontmost window once one is on screen;
2850
+ * other platforms report none.
2851
+ */
2852
+ export interface OpenedApplication {
2853
+ id: string
2854
+ name: string
2855
+ path: string
2856
+ running: boolean
2857
+ pid?: number
2858
+ window?: DesktopWindow
2859
+ }
2860
+
2747
2861
  /** Parsed Kitty keyboard protocol sequence result for a Kitty input sequence. */
2748
2862
  export interface ParsedKittyResult {
2749
2863
  /** Primary codepoint associated with the key. */
@@ -2843,6 +2957,26 @@ export interface PointerOptions {
2843
2957
  * default background delivery.
2844
2958
  */
2845
2959
  takeover?: boolean
2960
+ /**
2961
+ * With `takeover`, hand focus back to the user's app even if they typed
2962
+ * or clicked during the action; only a third app they switched to keeps
2963
+ * it. The host sets this when it reruns a refused background action.
2964
+ */
2965
+ returnFocus?: boolean
2966
+ /**
2967
+ * Item path to choose in the menu a click opens, matched like a menu-bar
2968
+ * path, e.g. a context menu's `["Add to", "Fonts"]`; the call opens the
2969
+ * menu, presses the item and returns with the menu closed.
2970
+ */
2971
+ menu?: Array<string>
2972
+ /**
2973
+ * Refuse a background left click that lands on a control that opens a
2974
+ * menu (on macOS a menu button or popup button), or a drag that starts on
2975
+ * one, with `BackgroundUnavailable` before anything is sent. The host sets
2976
+ * this when the user refuses foreground takeover: an open menu takes their
2977
+ * keyboard.
2978
+ */
2979
+ refuseMenu?: boolean
2846
2980
  }
2847
2981
 
2848
2982
  /**
package/native/index.js CHANGED
@@ -58,11 +58,13 @@ export const astEdit = nativeBindings.astEdit ?? missingNativeExport("astEdit");
58
58
  export const astGrep = nativeBindings.astGrep ?? missingNativeExport("astGrep");
59
59
  export const astMatch = nativeBindings.astMatch ?? missingNativeExport("astMatch");
60
60
  export const blockRangeAt = nativeBindings.blockRangeAt ?? missingNativeExport("blockRangeAt");
61
+ export const closeDesktopEventTaps = nativeBindings.closeDesktopEventTaps ?? missingNativeExport("closeDesktopEventTaps");
61
62
  export const copyToClipboard = nativeBindings.copyToClipboard ?? missingNativeExport("copyToClipboard");
62
63
  export const cosineSimilarityPairs = nativeBindings.cosineSimilarityPairs ?? missingNativeExport("cosineSimilarityPairs");
63
64
  export const countTokens = nativeBindings.countTokens ?? missingNativeExport("countTokens");
64
65
  export const decodeSixelToPng = nativeBindings.decodeSixelToPng ?? missingNativeExport("decodeSixelToPng");
65
66
  export const decodeSixelToPngAsync = nativeBindings.decodeSixelToPngAsync ?? missingNativeExport("decodeSixelToPngAsync");
67
+ export const desktopEscapeStops = nativeBindings.desktopEscapeStops ?? missingNativeExport("desktopEscapeStops");
66
68
  export const detectMacOSAppearance = nativeBindings.detectMacOSAppearance ?? missingNativeExport("detectMacOSAppearance");
67
69
  export const deviceCheckGenerateToken = nativeBindings.deviceCheckGenerateToken ?? missingNativeExport("deviceCheckGenerateToken");
68
70
  export const diffLineRuns = nativeBindings.diffLineRuns ?? missingNativeExport("diffLineRuns");
@@ -81,6 +83,7 @@ export const executeShell = nativeBindings.executeShell ?? missingNativeExport("
81
83
  export const expandWindowsLongPath = nativeBindings.expandWindowsLongPath ?? missingNativeExport("expandWindowsLongPath");
82
84
  export const extractInlineSloppyRegions = nativeBindings.extractInlineSloppyRegions ?? missingNativeExport("extractInlineSloppyRegions");
83
85
  export const extractSegments = nativeBindings.extractSegments ?? missingNativeExport("extractSegments");
86
+ export const forgetDesktopEscapeStops = nativeBindings.forgetDesktopEscapeStops ?? missingNativeExport("forgetDesktopEscapeStops");
84
87
  export const fuzzyFind = nativeBindings.fuzzyFind ?? missingNativeExport("fuzzyFind");
85
88
  export const getSupportedLanguages = nativeBindings.getSupportedLanguages ?? missingNativeExport("getSupportedLanguages");
86
89
  export const getWindowsShortPath = nativeBindings.getWindowsShortPath ?? missingNativeExport("getWindowsShortPath");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@linxiraos/pi-natives",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
4
4
  "description": "Native Rust bindings for PDF conversion, audio, WebRTC, grep, clipboard, image processing, syntax highlighting, PTY, and shell operations via N-API",
5
5
  "type": "module",
6
6
  "homepage": "https://linxira-os.github.io/zeta/",
@@ -110,11 +110,11 @@
110
110
  }
111
111
  },
112
112
  "optionalDependencies": {
113
- "@linxiraos/pi-natives-linux-x64": "1.3.0",
114
- "@linxiraos/pi-natives-linux-arm64": "1.3.0",
115
- "@linxiraos/pi-natives-darwin-x64": "1.3.0",
116
- "@linxiraos/pi-natives-darwin-arm64": "1.3.0",
117
- "@linxiraos/pi-natives-win32-x64": "1.3.0",
118
- "@linxiraos/pi-natives-win32-arm64": "1.3.0"
113
+ "@linxiraos/pi-natives-linux-x64": "1.3.2",
114
+ "@linxiraos/pi-natives-linux-arm64": "1.3.2",
115
+ "@linxiraos/pi-natives-darwin-x64": "1.3.2",
116
+ "@linxiraos/pi-natives-darwin-arm64": "1.3.2",
117
+ "@linxiraos/pi-natives-win32-x64": "1.3.2",
118
+ "@linxiraos/pi-natives-win32-arm64": "1.3.2"
119
119
  }
120
120
  }