uwonbot 1.2.1 → 1.2.3
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/bin/uwonbot.js +9 -7
- package/package.json +1 -1
- package/src/agent.js +106 -30
package/bin/uwonbot.js
CHANGED
|
@@ -9,12 +9,19 @@ import { startAgent } from '../src/agent.js';
|
|
|
9
9
|
import { runSetupWizard } from '../src/setup.js';
|
|
10
10
|
import { enableAutostart, disableAutostart, isAutostartEnabled } from '../src/autostart.js';
|
|
11
11
|
|
|
12
|
+
import { readFileSync } from 'fs';
|
|
13
|
+
import { fileURLToPath } from 'url';
|
|
14
|
+
import { dirname, join } from 'path';
|
|
15
|
+
|
|
16
|
+
const __uwonDir = dirname(fileURLToPath(import.meta.url));
|
|
17
|
+
const __uwonPkg = JSON.parse(readFileSync(join(__uwonDir, '..', 'package.json'), 'utf8'));
|
|
18
|
+
|
|
12
19
|
showBanner();
|
|
13
20
|
|
|
14
21
|
program
|
|
15
22
|
.name('uwonbot')
|
|
16
23
|
.description('Uwonbot AI Assistant — Your AI controls your computer')
|
|
17
|
-
.version(
|
|
24
|
+
.version(__uwonPkg.version);
|
|
18
25
|
|
|
19
26
|
program
|
|
20
27
|
.command('login')
|
|
@@ -130,12 +137,7 @@ program
|
|
|
130
137
|
console.log(chalk.cyan(' Checking for updates...'));
|
|
131
138
|
try {
|
|
132
139
|
const latest = execSync('npm view uwonbot version', { encoding: 'utf8' }).trim();
|
|
133
|
-
const
|
|
134
|
-
const { fileURLToPath } = await import('url');
|
|
135
|
-
const { dirname, join } = await import('path');
|
|
136
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
137
|
-
const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8'));
|
|
138
|
-
const current = pkg.version;
|
|
140
|
+
const current = __uwonPkg.version;
|
|
139
141
|
if (current === latest) {
|
|
140
142
|
console.log(chalk.green(` ✓ Already on latest version (v${current})`));
|
|
141
143
|
return;
|
package/package.json
CHANGED
package/src/agent.js
CHANGED
|
@@ -85,17 +85,21 @@ async function loadNativeModules() {
|
|
|
85
85
|
}
|
|
86
86
|
console.log(chalk.green(' ✓ nut-js loaded (mouse/keyboard control)'));
|
|
87
87
|
if (!accessOk) {
|
|
88
|
-
console.log(chalk.yellow(' ⚠ 접근성 권한이 없어
|
|
88
|
+
console.log(chalk.yellow(' ⚠ 접근성 권한이 없어 CoreGraphics 폴백을 사용합니다.'));
|
|
89
89
|
}
|
|
90
|
-
} catch {
|
|
90
|
+
} catch (nutErr) {
|
|
91
91
|
try {
|
|
92
92
|
const rjs = await import('robotjs');
|
|
93
93
|
robot = rjs.default || rjs;
|
|
94
94
|
console.log(chalk.green(' ✓ robotjs loaded (mouse/keyboard control)'));
|
|
95
95
|
} catch {
|
|
96
|
-
console.log(chalk.yellow(' ⚠ No mouse/keyboard module found.'));
|
|
97
|
-
console.log(chalk.yellow(' Install: npm install -g @nut-tree-fork/nut-js'));
|
|
98
96
|
robot = null;
|
|
97
|
+
if (platform === 'darwin') {
|
|
98
|
+
console.log(chalk.green(' ✓ CoreGraphics 직접 제어 모드 (macOS 네이티브)'));
|
|
99
|
+
} else {
|
|
100
|
+
console.log(chalk.yellow(' ⚠ No mouse/keyboard module found.'));
|
|
101
|
+
console.log(chalk.yellow(' Install: npm install -g @nut-tree-fork/nut-js'));
|
|
102
|
+
}
|
|
99
103
|
}
|
|
100
104
|
}
|
|
101
105
|
|
|
@@ -129,10 +133,25 @@ async function getScreenSize() {
|
|
|
129
133
|
return { width: 1920, height: 1080 };
|
|
130
134
|
}
|
|
131
135
|
|
|
136
|
+
async function cgMoveMouse(px, py) {
|
|
137
|
+
await execAsync(`osascript -l JavaScript -e 'ObjC.import("CoreGraphics"); $.CGWarpMouseCursorPosition($.CGPointMake(${px}, ${py}))'`);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async function cgMouseEvent(eventType, px, py, mouseButton = 0) {
|
|
141
|
+
const script = `ObjC.import("CoreGraphics");
|
|
142
|
+
var pt = $.CGPointMake(${px}, ${py});
|
|
143
|
+
var e = $.CGEventCreateMouseEvent($(), ${eventType}, pt, ${mouseButton});
|
|
144
|
+
$.CGEventPost($.kCGHIDEventTap, e);`;
|
|
145
|
+
await execAsync(`osascript -l JavaScript -e '${script.replace(/\n/g, ' ')}'`);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
let _lastKnownPos = { x: 960, y: 540 };
|
|
149
|
+
|
|
132
150
|
async function moveMouse(x, y) {
|
|
133
151
|
const screen = await getScreenSize();
|
|
134
152
|
const px = Math.round(x * screen.width);
|
|
135
153
|
const py = Math.round(y * screen.height);
|
|
154
|
+
_lastKnownPos = { x: px, y: py };
|
|
136
155
|
|
|
137
156
|
try {
|
|
138
157
|
if (robot?.mouse?.setPosition) {
|
|
@@ -143,9 +162,11 @@ async function moveMouse(x, y) {
|
|
|
143
162
|
robot.moveMouse(px, py);
|
|
144
163
|
return;
|
|
145
164
|
}
|
|
146
|
-
} catch {
|
|
165
|
+
} catch (e) {
|
|
166
|
+
console.log(chalk.gray(` [mouse] nut-js fallback: ${e.message}`));
|
|
167
|
+
}
|
|
147
168
|
if (platform === 'darwin') {
|
|
148
|
-
try { await
|
|
169
|
+
try { await cgMoveMouse(px, py); } catch {}
|
|
149
170
|
}
|
|
150
171
|
}
|
|
151
172
|
|
|
@@ -161,39 +182,86 @@ async function mouseClick(button = 'left', double = false) {
|
|
|
161
182
|
robot.mouseClick(button, double);
|
|
162
183
|
return;
|
|
163
184
|
}
|
|
164
|
-
} catch {
|
|
185
|
+
} catch (e) {
|
|
186
|
+
console.log(chalk.gray(` [click] nut-js fallback: ${e.message}`));
|
|
187
|
+
}
|
|
165
188
|
if (platform === 'darwin') {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
189
|
+
try {
|
|
190
|
+
const { x, y } = _lastKnownPos;
|
|
191
|
+
if (button === 'right') {
|
|
192
|
+
await cgMouseEvent('$.kCGEventRightMouseDown', x, y, '$.kCGMouseButtonRight');
|
|
193
|
+
await cgMouseEvent('$.kCGEventRightMouseUp', x, y, '$.kCGMouseButtonRight');
|
|
194
|
+
} else {
|
|
195
|
+
await cgMouseEvent('$.kCGEventLeftMouseDown', x, y, 0);
|
|
196
|
+
await cgMouseEvent('$.kCGEventLeftMouseUp', x, y, 0);
|
|
197
|
+
if (double) {
|
|
198
|
+
await new Promise(r => setTimeout(r, 50));
|
|
199
|
+
await cgMouseEvent('$.kCGEventLeftMouseDown', x, y, 0);
|
|
200
|
+
await cgMouseEvent('$.kCGEventLeftMouseUp', x, y, 0);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
} catch {}
|
|
169
204
|
}
|
|
170
205
|
}
|
|
171
206
|
|
|
172
207
|
async function mouseDown(button = 'left') {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
208
|
+
try {
|
|
209
|
+
if (robot?.mouse?.pressButton) {
|
|
210
|
+
const { Button } = await import('@nut-tree-fork/nut-js');
|
|
211
|
+
await robot.mouse.pressButton(button === 'right' ? Button.RIGHT : Button.LEFT);
|
|
212
|
+
return;
|
|
213
|
+
} else if (robot?.mouseToggle) {
|
|
214
|
+
robot.mouseToggle('down', button);
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
} catch {}
|
|
218
|
+
if (platform === 'darwin') {
|
|
219
|
+
const { x, y } = _lastKnownPos;
|
|
220
|
+
try {
|
|
221
|
+
if (button === 'right') await cgMouseEvent('$.kCGEventRightMouseDown', x, y, '$.kCGMouseButtonRight');
|
|
222
|
+
else await cgMouseEvent('$.kCGEventLeftMouseDown', x, y, 0);
|
|
223
|
+
} catch {}
|
|
178
224
|
}
|
|
179
225
|
}
|
|
180
226
|
|
|
181
227
|
async function mouseUp(button = 'left') {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
228
|
+
try {
|
|
229
|
+
if (robot?.mouse?.releaseButton) {
|
|
230
|
+
const { Button } = await import('@nut-tree-fork/nut-js');
|
|
231
|
+
await robot.mouse.releaseButton(button === 'right' ? Button.RIGHT : Button.LEFT);
|
|
232
|
+
return;
|
|
233
|
+
} else if (robot?.mouseToggle) {
|
|
234
|
+
robot.mouseToggle('up', button);
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
} catch {}
|
|
238
|
+
if (platform === 'darwin') {
|
|
239
|
+
const { x, y } = _lastKnownPos;
|
|
240
|
+
try {
|
|
241
|
+
if (button === 'right') await cgMouseEvent('$.kCGEventRightMouseUp', x, y, '$.kCGMouseButtonRight');
|
|
242
|
+
else await cgMouseEvent('$.kCGEventLeftMouseUp', x, y, 0);
|
|
243
|
+
} catch {}
|
|
187
244
|
}
|
|
188
245
|
}
|
|
189
246
|
|
|
190
247
|
async function mouseScroll(dx, dy) {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
248
|
+
try {
|
|
249
|
+
if (robot?.mouse?.scrollDown && robot?.mouse?.scrollUp) {
|
|
250
|
+
const amount = Math.abs(dy);
|
|
251
|
+
if (dy > 0) await robot.mouse.scrollDown(amount);
|
|
252
|
+
else await robot.mouse.scrollUp(amount);
|
|
253
|
+
return;
|
|
254
|
+
} else if (robot?.scrollMouse) {
|
|
255
|
+
robot.scrollMouse(dx, dy);
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
} catch {}
|
|
259
|
+
if (platform === 'darwin') {
|
|
260
|
+
const lines = Math.round(dy / 10) || (dy > 0 ? 1 : -1);
|
|
261
|
+
try {
|
|
262
|
+
const script = `ObjC.import("CoreGraphics"); var e = $.CGEventCreateScrollWheelEvent($(), 0, 1, ${-lines}); $.CGEventPost($.kCGHIDEventTap, e);`;
|
|
263
|
+
await execAsync(`osascript -l JavaScript -e '${script}'`);
|
|
264
|
+
} catch {}
|
|
197
265
|
}
|
|
198
266
|
}
|
|
199
267
|
|
|
@@ -207,10 +275,18 @@ async function mouseDrag(fromX, fromY, toX, toY) {
|
|
|
207
275
|
}
|
|
208
276
|
|
|
209
277
|
async function typeText(text) {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
278
|
+
try {
|
|
279
|
+
if (robot?.keyboard?.type) {
|
|
280
|
+
await robot.keyboard.type(text);
|
|
281
|
+
return;
|
|
282
|
+
} else if (robot?.typeString) {
|
|
283
|
+
robot.typeString(text);
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
} catch {}
|
|
287
|
+
if (platform === 'darwin') {
|
|
288
|
+
const escaped = text.replace(/'/g, "'\\''").replace(/"/g, '\\"');
|
|
289
|
+
try { await execAsync(`osascript -e 'tell application "System Events" to keystroke "${escaped}"'`); } catch {}
|
|
214
290
|
}
|
|
215
291
|
}
|
|
216
292
|
|