uwonbot 1.2.4 → 1.2.6

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/agent.js +53 -13
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uwonbot",
3
- "version": "1.2.4",
3
+ "version": "1.2.6",
4
4
  "description": "Uwonbot AI Assistant CLI — Your AI controls your computer",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/src/agent.js CHANGED
@@ -109,9 +109,20 @@ async function loadNativeModules() {
109
109
  console.log(chalk.green(' ✓ screenshot-desktop loaded'));
110
110
  } catch {
111
111
  console.log(chalk.yellow(' ⚠ screenshot-desktop not found.'));
112
- console.log(chalk.yellow(' Install: npm install -g screenshot-desktop'));
113
112
  screenshotDesktop = null;
114
113
  }
114
+
115
+ if (platform === 'darwin' && !robot) {
116
+ try {
117
+ await execAsync(`osascript -l JavaScript -e 'ObjC.import("CoreGraphics"); 0'`);
118
+ console.log(chalk.green(' ✓ CoreGraphics 마우스 제어 테스트 성공'));
119
+ } catch {
120
+ console.log(chalk.red(' ✗ CoreGraphics 사용 불가'));
121
+ }
122
+ }
123
+
124
+ const screen = await getScreenSize();
125
+ console.log(chalk.gray(` Screen: ${screen.width}x${screen.height}`));
115
126
  }
116
127
 
117
128
  async function getScreenSize() {
@@ -147,6 +158,7 @@ $.CGEventPost($.kCGHIDEventTap, e);`;
147
158
 
148
159
  let _lastKnownPos = { x: 960, y: 540 };
149
160
 
161
+ let _moveLogCount = 0;
150
162
  async function moveMouse(x, y) {
151
163
  const screen = await getScreenSize();
152
164
  const px = Math.round(x * screen.width);
@@ -157,16 +169,23 @@ async function moveMouse(x, y) {
157
169
  if (robot?.mouse?.setPosition) {
158
170
  const { Point } = await import('@nut-tree-fork/nut-js');
159
171
  await robot.mouse.setPosition(new Point(px, py));
172
+ if (_moveLogCount++ < 3) console.log(chalk.green(` [mouse] nut-js → (${px},${py})`));
160
173
  return;
161
174
  } else if (robot?.moveMouse) {
162
175
  robot.moveMouse(px, py);
176
+ if (_moveLogCount++ < 3) console.log(chalk.green(` [mouse] robotjs → (${px},${py})`));
163
177
  return;
164
178
  }
165
179
  } catch (e) {
166
- console.log(chalk.gray(` [mouse] nut-js fallback: ${e.message}`));
180
+ if (_moveLogCount++ < 5) console.log(chalk.yellow(` [mouse] nut-js failed: ${e.message}, trying CoreGraphics`));
167
181
  }
168
182
  if (platform === 'darwin') {
169
- try { await cgMoveMouse(px, py); } catch {}
183
+ try {
184
+ await cgMoveMouse(px, py);
185
+ if (_moveLogCount++ < 3) console.log(chalk.green(` [mouse] CoreGraphics → (${px},${py})`));
186
+ } catch (e) {
187
+ if (_moveLogCount++ < 5) console.log(chalk.red(` [mouse] CoreGraphics failed: ${e.message}`));
188
+ }
170
189
  }
171
190
  }
172
191
 
@@ -501,9 +520,14 @@ async function openTerminalWithChat(assistantName) {
501
520
  }
502
521
  }
503
522
 
523
+ let _logThrottle = 0;
504
524
  async function handleCommand(msg) {
505
525
  try {
506
526
  const cmd = JSON.parse(msg);
527
+ if (cmd.type !== 'mouse_move' || Date.now() - _logThrottle > 2000) {
528
+ if (cmd.type === 'mouse_move') _logThrottle = Date.now();
529
+ console.log(chalk.gray(` ← ${cmd.type}${cmd.type === 'mouse_move' ? ` (${cmd.x?.toFixed(3)},${cmd.y?.toFixed(3)})` : ''}`));
530
+ }
507
531
  switch (cmd.type) {
508
532
  case 'mouse_move':
509
533
  await moveMouse(cmd.x, cmd.y);
@@ -561,6 +585,16 @@ async function handleCommand(msg) {
561
585
  const wl = await windowList();
562
586
  return { ok: true, windows: wl };
563
587
  }
588
+ case 'open_url': {
589
+ const url = cmd.url;
590
+ if (!url) return { ok: false, error: 'No URL provided' };
591
+ try {
592
+ if (platform === 'darwin') await execAsync(`open "${url}"`);
593
+ else if (platform === 'win32') await execAsync(`start "" "${url}"`);
594
+ else await execAsync(`xdg-open "${url}"`);
595
+ return { ok: true };
596
+ } catch (e) { return { ok: false, error: e.message }; }
597
+ }
564
598
  case 'ping':
565
599
  return { ok: true, pong: true };
566
600
  default:
@@ -682,10 +716,22 @@ export async function startAgent(port = 9876, options = {}) {
682
716
  } catch {}
683
717
  console.log('');
684
718
 
719
+ let _assistantOpen = false;
720
+ let _clapCooldown = false;
721
+
685
722
  if (!options.noMic) {
686
723
  await ensureSox();
687
724
  const clapListener = new ClapListener(async () => {
725
+ if (_assistantOpen) {
726
+ console.log(chalk.gray(' 👏 박수 감지 — 이미 비서가 활성 상태입니다.'));
727
+ return;
728
+ }
729
+ if (_clapCooldown) return;
730
+ _clapCooldown = true;
731
+ setTimeout(() => { _clapCooldown = false; }, 5000);
732
+
688
733
  console.log(chalk.bold.cyan(' 👏 박수 감지! 비서 활성화 중...'));
734
+ _assistantOpen = true;
689
735
 
690
736
  if (userAssistants.length === 0) {
691
737
  console.log(chalk.gray(' → 기본 Uwonbot 웹 실행'));
@@ -701,16 +747,9 @@ export async function startAgent(port = 9876, options = {}) {
701
747
  return;
702
748
  }
703
749
 
704
- if (userAssistants.length === 1) {
705
- const a = userAssistants[0];
706
- console.log(chalk.green(` → ${a.name} 웹 실행`));
707
- await openWebAssistant(a.id);
708
- return;
709
- }
710
-
711
- const first = userAssistants[0];
712
- console.log(chalk.green(` → ${first.name} 웹 실행 (비서 ${userAssistants.length}개 중 첫 번째)`));
713
- await openWebAssistant(first.id);
750
+ const target = userAssistants[0];
751
+ console.log(chalk.green(` → ${target.name} 실행`));
752
+ await openWebAssistant(target.id);
714
753
  });
715
754
  await clapListener.start();
716
755
  console.log('');
@@ -733,6 +772,7 @@ export async function startAgent(port = 9876, options = {}) {
733
772
 
734
773
  ws.on('close', () => {
735
774
  console.log(chalk.yellow(' ○ Client disconnected'));
775
+ _assistantOpen = false;
736
776
  });
737
777
 
738
778
  ws.send(JSON.stringify({ type: 'welcome', agent: 'uwonbot', version: '1.1.2', uid }));