@aexol/spectral 0.9.212 → 0.9.216

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.
Files changed (115) hide show
  1. package/dist/backend/generated-images.d.ts +180 -0
  2. package/dist/backend/generated-images.d.ts.map +1 -0
  3. package/dist/backend/generated-images.js +483 -0
  4. package/dist/backend/machine-routing.d.ts +25 -0
  5. package/dist/backend/machine-routing.d.ts.map +1 -0
  6. package/dist/backend/machine-routing.js +35 -0
  7. package/dist/commands/logout.d.ts.map +1 -1
  8. package/dist/commands/logout.js +4 -0
  9. package/dist/commands/serve.d.ts.map +1 -1
  10. package/dist/commands/serve.js +20 -2
  11. package/dist/extensions/browser/browser-service.d.ts +75 -1
  12. package/dist/extensions/browser/browser-service.d.ts.map +1 -1
  13. package/dist/extensions/browser/browser-service.js +600 -34
  14. package/dist/extensions/browser/index.d.ts +10 -4
  15. package/dist/extensions/browser/index.d.ts.map +1 -1
  16. package/dist/extensions/browser/index.js +44 -5
  17. package/dist/extensions/browser/stream/stream-tool.d.ts +10 -0
  18. package/dist/extensions/browser/stream/stream-tool.d.ts.map +1 -1
  19. package/dist/extensions/browser/stream/stream-tool.js +42 -14
  20. package/dist/extensions/browser/tools/core.d.ts.map +1 -1
  21. package/dist/extensions/browser/tools/core.js +63 -2
  22. package/dist/extensions/desktop-control/index.d.ts +55 -0
  23. package/dist/extensions/desktop-control/index.d.ts.map +1 -0
  24. package/dist/extensions/desktop-control/index.js +633 -0
  25. package/dist/extensions/desktop-control/keys.d.ts +33 -0
  26. package/dist/extensions/desktop-control/keys.d.ts.map +1 -0
  27. package/dist/extensions/desktop-control/keys.js +170 -0
  28. package/dist/extensions/desktop-control/linux.d.ts +26 -0
  29. package/dist/extensions/desktop-control/linux.d.ts.map +1 -0
  30. package/dist/extensions/desktop-control/linux.js +195 -0
  31. package/dist/extensions/desktop-control/macos.d.ts +53 -0
  32. package/dist/extensions/desktop-control/macos.d.ts.map +1 -0
  33. package/dist/extensions/desktop-control/macos.js +382 -0
  34. package/dist/extensions/desktop-control/safety.d.ts +89 -0
  35. package/dist/extensions/desktop-control/safety.d.ts.map +1 -0
  36. package/dist/extensions/desktop-control/safety.js +157 -0
  37. package/dist/extensions/desktop-control/types.d.ts +79 -0
  38. package/dist/extensions/desktop-control/types.d.ts.map +1 -0
  39. package/dist/extensions/desktop-control/types.js +10 -0
  40. package/dist/extensions/desktop-control/windows.d.ts +31 -0
  41. package/dist/extensions/desktop-control/windows.d.ts.map +1 -0
  42. package/dist/extensions/desktop-control/windows.js +276 -0
  43. package/dist/extensions/desktop-screenshot/index.d.ts +103 -0
  44. package/dist/extensions/desktop-screenshot/index.d.ts.map +1 -1
  45. package/dist/extensions/desktop-screenshot/index.js +363 -17
  46. package/dist/extensions/image-generation/index.d.ts.map +1 -1
  47. package/dist/extensions/image-generation/index.js +133 -34
  48. package/dist/extensions/seo/index.d.ts.map +1 -1
  49. package/dist/extensions/seo/index.js +4 -0
  50. package/dist/extensions/seo/tools/backend-bridge.d.ts +4 -0
  51. package/dist/extensions/seo/tools/backend-bridge.d.ts.map +1 -0
  52. package/dist/extensions/seo/tools/backend-bridge.js +378 -0
  53. package/dist/extensions/seo/tools/full-audit.d.ts +2 -0
  54. package/dist/extensions/seo/tools/full-audit.d.ts.map +1 -1
  55. package/dist/extensions/seo/tools/full-audit.js +1 -1
  56. package/dist/extensions/seo/tools/report.d.ts +10 -0
  57. package/dist/extensions/seo/tools/report.d.ts.map +1 -1
  58. package/dist/extensions/seo/tools/report.js +1 -1
  59. package/dist/extensions/spectral-vision-fallback.d.ts.map +1 -1
  60. package/dist/extensions/spectral-vision-fallback.js +11 -1
  61. package/dist/generated/zeus/const.d.ts.map +1 -1
  62. package/dist/generated/zeus/const.js +121 -4
  63. package/dist/generated/zeus/index.d.ts +527 -0
  64. package/dist/generated/zeus/index.d.ts.map +1 -1
  65. package/dist/mcp/tool-registrar.d.ts.map +1 -1
  66. package/dist/mcp/tool-registrar.js +5 -2
  67. package/dist/mcp/types.d.ts +5 -0
  68. package/dist/mcp/types.d.ts.map +1 -1
  69. package/dist/relay/dispatcher.d.ts +12 -1
  70. package/dist/relay/dispatcher.d.ts.map +1 -1
  71. package/dist/relay/dispatcher.js +44 -42
  72. package/dist/sdk/ai/providers/faux.js +1 -1
  73. package/dist/sdk/ai/providers/openai-completions.d.ts.map +1 -1
  74. package/dist/sdk/ai/providers/openai-completions.js +69 -16
  75. package/dist/sdk/ai/providers/openrouter-images.d.ts.map +1 -1
  76. package/dist/sdk/ai/providers/openrouter-images.js +58 -9
  77. package/dist/sdk/ai/providers/simple-options.d.ts.map +1 -1
  78. package/dist/sdk/ai/providers/simple-options.js +2 -0
  79. package/dist/sdk/ai/types.d.ts +37 -1
  80. package/dist/sdk/ai/types.d.ts.map +1 -1
  81. package/dist/sdk/ai/utils/hosted-image-resolver.d.ts +60 -0
  82. package/dist/sdk/ai/utils/hosted-image-resolver.d.ts.map +1 -0
  83. package/dist/sdk/ai/utils/hosted-image-resolver.js +75 -0
  84. package/dist/sdk/ai/utils/image-source.d.ts +168 -0
  85. package/dist/sdk/ai/utils/image-source.d.ts.map +1 -0
  86. package/dist/sdk/ai/utils/image-source.js +487 -0
  87. package/dist/sdk/coding-agent/core/extensions/native-extensions.d.ts.map +1 -1
  88. package/dist/sdk/coding-agent/core/extensions/native-extensions.js +14 -0
  89. package/dist/sdk/coding-agent/core/extensions/types.d.ts +9 -0
  90. package/dist/sdk/coding-agent/core/extensions/types.d.ts.map +1 -1
  91. package/dist/sdk/coding-agent/core/system-prompt.d.ts.map +1 -1
  92. package/dist/sdk/coding-agent/core/system-prompt.js +15 -9
  93. package/dist/sdk/coding-agent/modes/rpc/rpc-mode.d.ts.map +1 -1
  94. package/dist/sdk/coding-agent/modes/rpc/rpc-mode.js +16 -3
  95. package/dist/sdk/coding-agent/utils/image-resize.d.ts.map +1 -1
  96. package/dist/sdk/coding-agent/utils/image-resize.js +7 -3
  97. package/dist/server/agent-bridge.d.ts +14 -0
  98. package/dist/server/agent-bridge.d.ts.map +1 -1
  99. package/dist/server/agent-bridge.js +105 -26
  100. package/dist/server/handlers/queue.d.ts.map +1 -1
  101. package/dist/server/handlers/queue.js +11 -34
  102. package/dist/server/image-attachments.d.ts +109 -0
  103. package/dist/server/image-attachments.d.ts.map +1 -0
  104. package/dist/server/image-attachments.js +195 -0
  105. package/dist/server/session-stream.d.ts +67 -0
  106. package/dist/server/session-stream.d.ts.map +1 -1
  107. package/dist/server/session-stream.js +222 -23
  108. package/dist/server/storage.d.ts.map +1 -1
  109. package/dist/server/storage.js +10 -31
  110. package/dist/server/ui/terminal-confirm.d.ts +145 -0
  111. package/dist/server/ui/terminal-confirm.d.ts.map +1 -0
  112. package/dist/server/ui/terminal-confirm.js +333 -0
  113. package/dist/server/wire.d.ts +30 -5
  114. package/dist/server/wire.d.ts.map +1 -1
  115. package/package.json +1 -1
@@ -0,0 +1,170 @@
1
+ /**
2
+ * Key name normalization + platform key tables.
3
+ *
4
+ * Chord notation: "cmd+c", "ctrl+shift+t", "enter", "alt+F4".
5
+ * Modifier aliases: cmd/command/meta/super/win -> "meta", option/alt -> "alt",
6
+ * control/ctrl -> "ctrl", plus the unicode glyphs ⌘ ⌥ ⇧ ⌃.
7
+ */
8
+ const MODIFIER_ALIASES = {
9
+ ctrl: "ctrl",
10
+ control: "ctrl",
11
+ "⌃": "ctrl",
12
+ shift: "shift",
13
+ "⇧": "shift",
14
+ alt: "alt",
15
+ option: "alt",
16
+ opt: "alt",
17
+ "⌥": "alt",
18
+ cmd: "meta",
19
+ command: "meta",
20
+ meta: "meta",
21
+ super: "meta",
22
+ win: "meta",
23
+ windows: "meta",
24
+ "⌘": "meta",
25
+ };
26
+ const KEY_ALIASES = {
27
+ return: "return",
28
+ enter: "return",
29
+ esc: "escape",
30
+ del: "backspace",
31
+ spacebar: "space",
32
+ page_up: "pageup",
33
+ page_down: "pagedown",
34
+ pgup: "pageup",
35
+ pgdn: "pagedown",
36
+ arrowup: "up",
37
+ arrowdown: "down",
38
+ arrowleft: "left",
39
+ arrowright: "right",
40
+ minus: "-",
41
+ hyphen: "-",
42
+ equal: "=",
43
+ equals: "=",
44
+ bracketleft: "[",
45
+ bracketright: "]",
46
+ backslash: "\\",
47
+ semicolon: ";",
48
+ quote: "'",
49
+ apostrophe: "'",
50
+ comma: ",",
51
+ period: ".",
52
+ dot: ".",
53
+ slash: "/",
54
+ grave: "`",
55
+ backquote: "`",
56
+ };
57
+ const PUNCTUATION = new Set(["-", "=", "[", "]", "\\", ";", "'", ",", ".", "/", "`", "+"]);
58
+ /** macOS virtual keycodes for common keys (kVK_* from Events.h). */
59
+ export const MACOS_KEYCODES = {
60
+ a: 0, s: 1, d: 2, f: 3, h: 4, g: 5, z: 6, x: 7, c: 8, v: 9, b: 11,
61
+ q: 12, w: 13, e: 14, r: 15, y: 16, t: 17,
62
+ u: 32, i: 34, o: 31, p: 35,
63
+ l: 37, j: 38, k: 40, n: 45, m: 46,
64
+ "0": 29, "1": 18, "2": 19, "3": 20, "4": 21, "5": 23, "6": 22, "7": 26, "8": 28, "9": 25,
65
+ return: 36, tab: 48, space: 49, backspace: 51, escape: 53, delete: 117,
66
+ home: 115, end: 119, pageup: 116, pagedown: 121,
67
+ left: 123, right: 124, down: 125, up: 126, capslock: 57,
68
+ f1: 122, f2: 120, f3: 99, f4: 118, f5: 96, f6: 97, f7: 98, f8: 100,
69
+ f9: 101, f10: 109, f11: 103, f12: 111,
70
+ "-": 27, "=": 24, "[": 33, "]": 30, "\\": 42, ";": 41, "'": 39,
71
+ ",": 43, ".": 47, "/": 44, "`": 50,
72
+ };
73
+ /** Shifted ASCII char -> base key (typed with FLAG_SHIFT). */
74
+ export const MACOS_SHIFTED = {
75
+ "!": "1", "@": "2", "#": "3", $: "4", "%": "5", "^": "6", "&": "7",
76
+ "*": "8", "(": "9", ")": "0", _: "-", "+": "=", "{": "[", "}": "]",
77
+ "|": "\\", ":": ";", '"': "'", "<": ",", ">": ".", "?": "/", "~": "`",
78
+ };
79
+ // Uppercase letters are typed as shift+lowercase.
80
+ for (let i = 0; i < 26; i++) {
81
+ MACOS_SHIFTED[String.fromCharCode(65 + i)] = String.fromCharCode(97 + i);
82
+ }
83
+ /** CGEventFlagMask values. */
84
+ export const MACOS_MODIFIER_FLAGS = {
85
+ ctrl: 1 << 18, // 262144 kCGEventFlagMaskControl
86
+ shift: 1 << 17, // 131072 kCGEventFlagMaskShift
87
+ alt: 1 << 19, // 524288 kCGEventFlagMaskAlternate
88
+ meta: 1 << 20, // 1048576 kCGEventFlagMaskCommand
89
+ };
90
+ /** Windows virtual-key codes. */
91
+ export const WINDOWS_VK = {
92
+ a: 0x41, b: 0x42, c: 0x43, d: 0x44, e: 0x45, f: 0x46, g: 0x47, h: 0x48,
93
+ i: 0x49, j: 0x4a, k: 0x4b, l: 0x4c, m: 0x4d, n: 0x4e, o: 0x4f, p: 0x50,
94
+ q: 0x51, r: 0x52, s: 0x53, t: 0x54, u: 0x55, v: 0x56, w: 0x57, x: 0x58,
95
+ y: 0x59, z: 0x5a,
96
+ "0": 0x30, "1": 0x31, "2": 0x32, "3": 0x33, "4": 0x34,
97
+ "5": 0x35, "6": 0x36, "7": 0x37, "8": 0x38, "9": 0x39,
98
+ return: 0x0d, tab: 0x09, space: 0x20, escape: 0x1b, backspace: 0x08,
99
+ delete: 0x2e, home: 0x24, end: 0x23, pageup: 0x21, pagedown: 0x22,
100
+ left: 0x25, up: 0x26, right: 0x27, down: 0x28, capslock: 0x14,
101
+ f1: 0x70, f2: 0x71, f3: 0x72, f4: 0x73, f5: 0x74, f6: 0x75, f7: 0x76,
102
+ f8: 0x77, f9: 0x78, f10: 0x79, f11: 0x7a, f12: 0x7b,
103
+ "-": 0xbd, "=": 0xbb, ",": 0xbc, ".": 0xbe, ";": 0xba, "'": 0xde,
104
+ "/": 0xbf, "\\": 0xdc, "[": 0xdb, "]": 0xdd, "`": 0xc0,
105
+ };
106
+ export const WINDOWS_MODIFIER_VK = {
107
+ ctrl: 0x11, // VK_CONTROL
108
+ shift: 0x10, // VK_SHIFT
109
+ alt: 0x12, // VK_MENU
110
+ meta: 0x5b, // VK_LWIN
111
+ };
112
+ /** X keysym names for xdotool/wtype. */
113
+ export const XDOTOOL_KEYS = {
114
+ return: "Return", tab: "Tab", space: "space", escape: "Escape",
115
+ backspace: "BackSpace", delete: "Delete", home: "Home", end: "End",
116
+ pageup: "Prior", pagedown: "Next",
117
+ left: "Left", up: "Up", right: "Right", down: "Down", capslock: "Caps_Lock",
118
+ "-": "minus", "=": "equal", "[": "bracketleft", "]": "bracketright",
119
+ "\\": "backslash", ";": "semicolon", "'": "apostrophe", ",": "comma",
120
+ ".": "period", "/": "slash", "`": "grave",
121
+ };
122
+ export const XDOTOOL_MODIFIERS = {
123
+ ctrl: "ctrl", shift: "shift", alt: "alt", meta: "super",
124
+ };
125
+ export function asModifier(raw) {
126
+ return MODIFIER_ALIASES[raw.trim().toLowerCase()] ?? null;
127
+ }
128
+ /** Normalize a key name; returns the input lowercased when unknown (callers decide what to do). */
129
+ export function normalizeKey(raw) {
130
+ const k = raw.trim().toLowerCase();
131
+ if (KEY_ALIASES[k])
132
+ return KEY_ALIASES[k];
133
+ if (k.length === 1 && /[a-z0-9]/.test(k))
134
+ return k;
135
+ if (PUNCTUATION.has(k))
136
+ return k;
137
+ if (/^f([1-9]|1[0-2])$/.test(k))
138
+ return k;
139
+ return k;
140
+ }
141
+ export function isModifierToken(raw) {
142
+ return asModifier(raw) !== null;
143
+ }
144
+ /**
145
+ * Parse a chord like "cmd+shift+t" into modifiers + final key.
146
+ * Returns null for empty input or multiple non-modifier keys.
147
+ */
148
+ export function parseChord(raw) {
149
+ const parts = raw.split("+").map((p) => p.trim()).filter((p) => p.length > 0);
150
+ if (parts.length === 0)
151
+ return null;
152
+ const modifiers = [];
153
+ let key = "";
154
+ for (let i = 0; i < parts.length; i++) {
155
+ const mod = asModifier(parts[i]);
156
+ if (mod && i < parts.length - 1) {
157
+ if (!modifiers.includes(mod))
158
+ modifiers.push(mod);
159
+ }
160
+ else if (key === "") {
161
+ key = normalizeKey(parts[i]);
162
+ }
163
+ else {
164
+ return null; // two non-modifier tokens in one chord
165
+ }
166
+ }
167
+ if (!key)
168
+ return null;
169
+ return { modifiers, key };
170
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Linux adapter for desktop-control.
3
+ *
4
+ * Session detection (XDG_SESSION_TYPE, with WAYLAND_DISPLAY / DISPLAY
5
+ * fallbacks):
6
+ * - X11: xdotool for everything (mousemove, click, mousedown/mouseup drag,
7
+ * click 4/5/6/7 scrolling, type, key chords, windowactivate focus).
8
+ * - Wayland: wtype (virtual keyboard protocol) for type_text/hotkey only.
9
+ * Mouse/scroll/focus need a compositor-specific tool (ydotool requires a
10
+ * privileged uinput daemon) — intentionally not attempted.
11
+ * - No capable tool present: adapter is null and the extension registers
12
+ * nothing, logging a clear capability error.
13
+ */
14
+ import type { DesktopAction, DesktopAdapter } from "./types.js";
15
+ export declare function sessionType(env?: NodeJS.ProcessEnv): "x11" | "wayland" | "unknown";
16
+ export declare function buildXdotoolArgs(action: DesktopAction): string[];
17
+ export declare const xdotoolAdapter: DesktopAdapter;
18
+ export declare function buildWtypeTypeArgs(text: string): string[];
19
+ /** wtype press/release chord: -P each modifier and the key, then -R in reverse. */
20
+ export declare function buildWtypeHotkeyArgs(tokens: string[]): string[];
21
+ export declare const waylandKeysAdapter: DesktopAdapter;
22
+ export declare function createLinuxAdapter(env?: NodeJS.ProcessEnv): Promise<{
23
+ adapter: DesktopAdapter | null;
24
+ reason?: string;
25
+ }>;
26
+ //# sourceMappingURL=linux.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linux.d.ts","sourceRoot":"","sources":["../../../src/extensions/desktop-control/linux.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAKhE,wBAAgB,WAAW,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,KAAK,GAAG,SAAS,GAAG,SAAS,CAM/F;AAgDD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,EAAE,CAsChE;AAED,eAAO,MAAM,cAAc,EAAE,cAqB5B,CAAC;AAMF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAEzD;AAED,mFAAmF;AACnF,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAK/D;AAED,eAAO,MAAM,kBAAkB,EAAE,cAuBhC,CAAC;AAMF,wBAAsB,kBAAkB,CACtC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAAC;IAAE,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAwB9D"}
@@ -0,0 +1,195 @@
1
+ /**
2
+ * Linux adapter for desktop-control.
3
+ *
4
+ * Session detection (XDG_SESSION_TYPE, with WAYLAND_DISPLAY / DISPLAY
5
+ * fallbacks):
6
+ * - X11: xdotool for everything (mousemove, click, mousedown/mouseup drag,
7
+ * click 4/5/6/7 scrolling, type, key chords, windowactivate focus).
8
+ * - Wayland: wtype (virtual keyboard protocol) for type_text/hotkey only.
9
+ * Mouse/scroll/focus need a compositor-specific tool (ydotool requires a
10
+ * privileged uinput daemon) — intentionally not attempted.
11
+ * - No capable tool present: adapter is null and the extension registers
12
+ * nothing, logging a clear capability error.
13
+ */
14
+ import { execFile } from "node:child_process";
15
+ import { XDOTOOL_KEYS, XDOTOOL_MODIFIERS, isModifierToken, normalizeKey } from "./keys.js";
16
+ const TIMEOUT_MS = 10_000;
17
+ export function sessionType(env = process.env) {
18
+ const s = (env.XDG_SESSION_TYPE ?? "").toLowerCase();
19
+ if (s === "x11" || s === "wayland")
20
+ return s;
21
+ if (env.WAYLAND_DISPLAY)
22
+ return "wayland";
23
+ if (env.DISPLAY)
24
+ return "x11";
25
+ return "unknown";
26
+ }
27
+ function hasBinary(bin) {
28
+ return new Promise((resolve) => {
29
+ execFile("which", [bin], (err) => resolve(!err));
30
+ });
31
+ }
32
+ function runXdotool(args) {
33
+ return new Promise((resolve, reject) => {
34
+ execFile("xdotool", args, { timeout: TIMEOUT_MS }, (err, stdout, stderr) => {
35
+ if (err) {
36
+ const tail = String(stderr || err.message).trim().split("\n").pop() ?? err.message;
37
+ reject(new Error(`xdotool: ${tail}`));
38
+ }
39
+ else {
40
+ resolve(stdout);
41
+ }
42
+ });
43
+ });
44
+ }
45
+ function runWtype(args) {
46
+ return new Promise((resolve, reject) => {
47
+ execFile("wtype", args, { timeout: TIMEOUT_MS }, (err, _stdout, stderr) => {
48
+ if (err) {
49
+ const tail = String(stderr || err.message).trim().split("\n").pop() ?? err.message;
50
+ reject(new Error(`wtype: ${tail}`));
51
+ }
52
+ else {
53
+ resolve();
54
+ }
55
+ });
56
+ });
57
+ }
58
+ // ---------------------------------------------------------------------------
59
+ // xdotool (X11) builder — exported for unit tests (pure)
60
+ // ---------------------------------------------------------------------------
61
+ /** xdotool click button numbers: 1=left, 2=middle, 3=right, 4/5=vscroll, 6/7=hscroll. */
62
+ const XDO_MOUSE_BTN = { left: 1, middle: 2, right: 3 };
63
+ function xdoKey(token) {
64
+ const mod = isModifierToken(token) ? XDOTOOL_MODIFIERS[token] : undefined;
65
+ if (mod)
66
+ return mod;
67
+ const key = normalizeKey(token);
68
+ return XDOTOOL_KEYS[key] ?? key;
69
+ }
70
+ export function buildXdotoolArgs(action) {
71
+ switch (action.kind) {
72
+ case "mouse_move":
73
+ return ["mousemove", String(action.x), String(action.y)];
74
+ case "mouse_click":
75
+ return [
76
+ "mousemove", String(action.x), String(action.y),
77
+ "click", "--repeat", String(action.clickCount), String(XDO_MOUSE_BTN[action.button]),
78
+ ];
79
+ case "mouse_drag": {
80
+ const btn = String(XDO_MOUSE_BTN.left);
81
+ return [
82
+ "mousemove", String(action.fromX), String(action.fromY),
83
+ "mousedown", btn,
84
+ "mousemove", String(action.toX), String(action.toY),
85
+ "mouseup", btn,
86
+ ];
87
+ }
88
+ case "scroll": {
89
+ const args = [];
90
+ if (action.x !== undefined)
91
+ args.push("mousemove", String(action.x), String(action.y));
92
+ if (action.dy !== 0) {
93
+ args.push("click", "--repeat", String(Math.abs(action.dy)), action.dy > 0 ? "5" : "4");
94
+ }
95
+ if (action.dx !== 0) {
96
+ args.push("click", "--repeat", String(Math.abs(action.dx)), action.dx > 0 ? "7" : "6");
97
+ }
98
+ return args;
99
+ }
100
+ case "type_text":
101
+ return ["type", "--delay", "12", "--", action.text];
102
+ case "hotkey":
103
+ return ["key", "--clearmodifiers", action.tokens.map(xdoKey).join("+")];
104
+ case "focus_window":
105
+ return action.windowId !== undefined
106
+ ? ["windowactivate", "--sync", String(action.windowId)]
107
+ : ["search", "--name", action.title, "windowactivate", "--sync"];
108
+ }
109
+ }
110
+ export const xdotoolAdapter = {
111
+ platform: "linux-x11",
112
+ capabilities: ["mouse_move", "mouse_click", "mouse_drag", "scroll", "type_text", "hotkey", "focus_window"],
113
+ async frontmostApp() {
114
+ try {
115
+ const out = await runXdotool(["getactivewindow", "getwindowname"]);
116
+ const name = out.trim();
117
+ return name.length > 0 ? name : null;
118
+ }
119
+ catch {
120
+ return null;
121
+ }
122
+ },
123
+ buildPlan(action) {
124
+ return `xdotool ${buildXdotoolArgs(action).map((a) => JSON.stringify(a)).join(" ")}`;
125
+ },
126
+ async execute(action) {
127
+ await runXdotool(buildXdotoolArgs(action));
128
+ },
129
+ };
130
+ // ---------------------------------------------------------------------------
131
+ // wtype (Wayland, keyboard-only) builder — exported for unit tests (pure)
132
+ // ---------------------------------------------------------------------------
133
+ export function buildWtypeTypeArgs(text) {
134
+ return ["--", text];
135
+ }
136
+ /** wtype press/release chord: -P each modifier and the key, then -R in reverse. */
137
+ export function buildWtypeHotkeyArgs(tokens) {
138
+ const args = [];
139
+ for (const t of tokens)
140
+ args.push("-P", xdoKey(t));
141
+ for (const t of [...tokens].reverse())
142
+ args.push("-R", xdoKey(t));
143
+ return args;
144
+ }
145
+ export const waylandKeysAdapter = {
146
+ platform: "linux-wayland",
147
+ capabilities: ["type_text", "hotkey"],
148
+ async frontmostApp() {
149
+ return null; // no portable Wayland query
150
+ },
151
+ buildPlan(action) {
152
+ if (action.kind === "type_text") {
153
+ return `wtype ${JSON.stringify("--")} ${JSON.stringify(action.text)}`;
154
+ }
155
+ if (action.kind === "hotkey") {
156
+ return `wtype ${buildWtypeHotkeyArgs(action.tokens).map((a) => JSON.stringify(a)).join(" ")}`;
157
+ }
158
+ return `wtype: unsupported on Wayland (${action.kind})`;
159
+ },
160
+ async execute(action) {
161
+ if (action.kind === "type_text")
162
+ return runWtype(buildWtypeTypeArgs(action.text));
163
+ if (action.kind === "hotkey")
164
+ return runWtype(buildWtypeHotkeyArgs(action.tokens));
165
+ throw new Error(`${action.kind} is not supported on Wayland (wtype is keyboard-only)`);
166
+ },
167
+ };
168
+ // ---------------------------------------------------------------------------
169
+ // Adapter factory (probes the session for a capable backend)
170
+ // ---------------------------------------------------------------------------
171
+ export async function createLinuxAdapter(env = process.env) {
172
+ const session = sessionType(env);
173
+ if (session === "x11") {
174
+ if (!(await hasBinary("xdotool"))) {
175
+ return { adapter: null, reason: "X11 session but xdotool is not installed (sudo apt install xdotool / dnf install xdotool)" };
176
+ }
177
+ return { adapter: xdotoolAdapter };
178
+ }
179
+ if (session === "wayland") {
180
+ if (await hasBinary("wtype"))
181
+ return { adapter: waylandKeysAdapter };
182
+ return {
183
+ adapter: null,
184
+ reason: "Wayland session: only wtype (keyboard-only) is supported, and it is not installed. " +
185
+ "Install wtype for type/hotkey support; mouse/scroll/focus are not available on Wayland without a compositor-specific uinput daemon (ydotool).",
186
+ };
187
+ }
188
+ if (env.DISPLAY && (await hasBinary("xdotool"))) {
189
+ return { adapter: xdotoolAdapter };
190
+ }
191
+ return {
192
+ adapter: null,
193
+ reason: `unknown Linux session type (XDG_SESSION_TYPE=${env.XDG_SESSION_TYPE ?? "unset"}, WAYLAND_DISPLAY=${env.WAYLAND_DISPLAY ?? "unset"}, DISPLAY=${env.DISPLAY ?? "unset"}); install xdotool for X11 support`,
194
+ };
195
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * macOS adapter for desktop-control.
3
+ *
4
+ * Mouse/keyboard injection via JXA (`osascript -l JavaScript`) using the ObjC
5
+ * bridge to CoreGraphics: CGEventCreateMouseEvent + CGEventPost,
6
+ * CGEventCreateKeyboardEvent for keys, CGEventCreateScrollWheelEvent for
7
+ * scrolling. Numeric enum constants are inlined (kCGEventLeftMouseDown = 1,
8
+ * kCGHIDEventTap = 0, ...) so the script never depends on enum bridging.
9
+ *
10
+ * type_text uses CGEvent key events for ASCII; any non-ASCII text falls back
11
+ * to System Events `keystroke` via AppleScript (handles unicode).
12
+ *
13
+ * Every JXA action ends with a CGEventGetLocation read-back (cursor position)
14
+ * that the safety layer appends to the tool result — CGEventPost itself never
15
+ * errors, so the read-back is how silent injection failures surface.
16
+ *
17
+ * checkPermissions also preflights Screen Recording via
18
+ * CGPreflightScreenCaptureAccess (read-only) so mutating actions fail with
19
+ * fix instructions BEFORE the BEFORE screenshot would silently capture the
20
+ * desktop wallpaper.
21
+ *
22
+ * Accessibility (TCC) check + frontmost app query go through a read-only
23
+ * System Events query: `name of first application process whose frontmost is
24
+ * true`. When accessibility is missing, osascript fails with
25
+ * "osascript is not allowed assistive access" and we return guidance pointing
26
+ * to System Settings > Privacy & Security > Accessibility.
27
+ */
28
+ import type { DesktopAction, DesktopAdapter } from "./types.js";
29
+ export declare function buildMouseJxa(action: Extract<DesktopAction, {
30
+ kind: "mouse_move" | "mouse_click" | "mouse_drag" | "scroll";
31
+ }>): string;
32
+ /** Build the key sequence [[keycode, shift], ...] for ASCII text; null when any char is unmappable. */
33
+ export declare function buildAsciiTypeSeq(text: string): Array<[number, boolean]> | null;
34
+ export declare function buildTypeJxa(seq: Array<[number, boolean]>): string;
35
+ /** Tokens: leading modifiers + exactly one key. Throws on unsupported keys. */
36
+ export declare function resolveChordTokens(tokens: string[]): {
37
+ key: number;
38
+ flags: number;
39
+ };
40
+ export declare function buildHotkeyJxa(key: number, flags: number): string;
41
+ /** System Events keystroke; \n -> `return`, \t -> `tab` via concatenation. */
42
+ export declare function buildKeystrokeAppleScript(text: string): string;
43
+ export declare function buildFocusAppleScript(owner: string, title?: string): string;
44
+ export declare function accessibilityError(rawStderr: string): string;
45
+ export declare const SCREEN_RECORDING_ERROR: string;
46
+ /**
47
+ * One-shot JXA probe: CGPreflightScreenCaptureAccess() — true when Screen
48
+ * Recording TCC is granted. The function is missing from CoreGraphics'
49
+ * bridgesupport on current macOS, so it is bound explicitly via ObjC.bindFunction.
50
+ */
51
+ export declare function buildScreenCapturePreflightJxa(): string;
52
+ export declare const macosAdapter: DesktopAdapter;
53
+ //# sourceMappingURL=macos.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"macos.d.ts","sourceRoot":"","sources":["../../../src/extensions/desktop-control/macos.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAOH,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAmB,MAAM,YAAY,CAAC;AA+CjF,wBAAgB,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,EAAE;IAAE,IAAI,EAAE,YAAY,GAAG,aAAa,GAAG,YAAY,GAAG,QAAQ,CAAA;CAAE,CAAC,GAAG,MAAM,CA2CtI;AAED,uGAAuG;AACvG,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI,CAW/E;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM,CAUlE;AAED,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAanF;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAOjE;AAUD,8EAA8E;AAC9E,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAW9D;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAsB3E;AAuED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAiB5D;AAMD,eAAO,MAAM,sBAAsB,QAI4B,CAAC;AAEhE;;;;GAIG;AACH,wBAAgB,8BAA8B,IAAI,MAAM,CAMvD;AAoBD,eAAO,MAAM,YAAY,EAAE,cA8E1B,CAAC"}