uwonbot 1.1.8 → 1.1.9

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 +132 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uwonbot",
3
- "version": "1.1.8",
3
+ "version": "1.1.9",
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
@@ -221,6 +221,118 @@ async function takeScreenshot() {
221
221
  }
222
222
  }
223
223
 
224
+ // ─── Window Management ───
225
+
226
+ async function windowFrontmost() {
227
+ try {
228
+ if (platform === 'darwin') {
229
+ const { stdout } = await execAsync(`osascript -e '
230
+ tell application "System Events"
231
+ set fp to first application process whose frontmost is true
232
+ set appName to name of fp
233
+ try
234
+ set w to front window of fp
235
+ set {px, py} to position of w
236
+ set {sw, sh} to size of w
237
+ return appName & "||" & px & "," & py & "||" & sw & "," & sh
238
+ end try
239
+ return appName & "||0,0||800,600"
240
+ end tell'`);
241
+ const parts = stdout.trim().split('||');
242
+ const [px, py] = (parts[1] || '0,0').split(',').map(Number);
243
+ const [sw, sh] = (parts[2] || '800,600').split(',').map(Number);
244
+ return { app: parts[0], x: px, y: py, width: sw, height: sh };
245
+ } else if (platform === 'win32') {
246
+ const { stdout } = await execAsync(`powershell -Command "[Console]::OutputEncoding = [Text.Encoding]::UTF8; Add-Type -TypeDefinition 'using System; using System.Runtime.InteropServices; public class Win { [DllImport(\\\"user32.dll\\\")] public static extern IntPtr GetForegroundWindow(); [DllImport(\\\"user32.dll\\\")] public static extern bool GetWindowRect(IntPtr h, out RECT r); [StructLayout(LayoutKind.Sequential)] public struct RECT { public int L,T,R,B; } }'; $h=[Win]::GetForegroundWindow(); $r=New-Object Win+RECT; [Win]::GetWindowRect($h,[ref]$r); Write-Output ($r.L.ToString()+','+$r.T.ToString()+'||'+($r.R-$r.L).ToString()+','+($r.B-$r.T).ToString())"`);
247
+ const parts = stdout.trim().split('||');
248
+ const [px, py] = (parts[0] || '0,0').split(',').map(Number);
249
+ const [sw, sh] = (parts[1] || '800,600').split(',').map(Number);
250
+ return { app: 'foreground', x: px, y: py, width: sw, height: sh };
251
+ }
252
+ return { app: 'unknown', x: 0, y: 0, width: 800, height: 600 };
253
+ } catch (e) { return { app: 'unknown', x: 0, y: 0, width: 800, height: 600 }; }
254
+ }
255
+
256
+ async function windowMove(app, x, y) {
257
+ try {
258
+ if (platform === 'darwin') {
259
+ const script = app
260
+ ? `tell application "System Events" to tell process "${app}" to set position of front window to {${Math.round(x)}, ${Math.round(y)}}`
261
+ : `tell application "System Events"
262
+ set fp to first application process whose frontmost is true
263
+ set position of front window of fp to {${Math.round(x)}, ${Math.round(y)}}
264
+ end tell`;
265
+ await execAsync(`osascript -e '${script}'`);
266
+ } else if (platform === 'win32') {
267
+ await execAsync(`powershell -Command "Add-Type -TypeDefinition 'using System; using System.Runtime.InteropServices; public class WM { [DllImport(\\\"user32.dll\\\")] public static extern IntPtr GetForegroundWindow(); [DllImport(\\\"user32.dll\\\")] public static extern bool MoveWindow(IntPtr h,int x,int y,int w,int h2,bool r); [DllImport(\\\"user32.dll\\\")] public static extern bool GetWindowRect(IntPtr h,out RECT r); [StructLayout(LayoutKind.Sequential)] public struct RECT{public int L,T,R,B;} }'; $h=[WM]::GetForegroundWindow(); $r=New-Object WM+RECT; [WM]::GetWindowRect($h,[ref]$r); [WM]::MoveWindow($h,${Math.round(x)},${Math.round(y)},$r.R-$r.L,$r.B-$r.T,$true)"`);
268
+ }
269
+ return true;
270
+ } catch { return false; }
271
+ }
272
+
273
+ async function windowResize(app, w, h) {
274
+ try {
275
+ if (platform === 'darwin') {
276
+ const script = app
277
+ ? `tell application "System Events" to tell process "${app}" to set size of front window to {${Math.round(w)}, ${Math.round(h)}}`
278
+ : `tell application "System Events"
279
+ set fp to first application process whose frontmost is true
280
+ set size of front window of fp to {${Math.round(w)}, ${Math.round(h)}}
281
+ end tell`;
282
+ await execAsync(`osascript -e '${script}'`);
283
+ } else if (platform === 'win32') {
284
+ await execAsync(`powershell -Command "Add-Type -TypeDefinition 'using System; using System.Runtime.InteropServices; public class WR { [DllImport(\\\"user32.dll\\\")] public static extern IntPtr GetForegroundWindow(); [DllImport(\\\"user32.dll\\\")] public static extern bool MoveWindow(IntPtr h,int x,int y,int w,int h2,bool r); [DllImport(\\\"user32.dll\\\")] public static extern bool GetWindowRect(IntPtr h,out RECT r); [StructLayout(LayoutKind.Sequential)] public struct RECT{public int L,T,R,B;} }'; $h=[WR]::GetForegroundWindow(); $r=New-Object WR+RECT; [WR]::GetWindowRect($h,[ref]$r); [WR]::MoveWindow($h,$r.L,$r.T,${Math.round(w)},${Math.round(h)},$true)"`);
285
+ }
286
+ return true;
287
+ } catch { return false; }
288
+ }
289
+
290
+ async function windowClose(app) {
291
+ try {
292
+ if (platform === 'darwin') {
293
+ const script = app
294
+ ? `tell application "${app}" to close front window`
295
+ : `tell application "System Events"
296
+ set fp to first application process whose frontmost is true
297
+ tell fp to click (first button of front window whose subrole is "AXCloseButton")
298
+ end tell`;
299
+ await execAsync(`osascript -e '${script}'`);
300
+ } else if (platform === 'win32') {
301
+ await execAsync(`powershell -Command "Add-Type -TypeDefinition 'using System; using System.Runtime.InteropServices; public class WC { [DllImport(\\\"user32.dll\\\")] public static extern IntPtr GetForegroundWindow(); [DllImport(\\\"user32.dll\\\")] public static extern bool PostMessage(IntPtr h,uint m,IntPtr w,IntPtr l); }'; [WC]::PostMessage([WC]::GetForegroundWindow(),0x0010,[IntPtr]::Zero,[IntPtr]::Zero)"`);
302
+ }
303
+ return true;
304
+ } catch { return false; }
305
+ }
306
+
307
+ async function windowList() {
308
+ try {
309
+ if (platform === 'darwin') {
310
+ const { stdout } = await execAsync(`osascript -e '
311
+ set output to ""
312
+ tell application "System Events"
313
+ repeat with p in (every application process whose visible is true)
314
+ set pName to name of p
315
+ try
316
+ repeat with w in (every window of p)
317
+ set {px, py} to position of w
318
+ set {sw, sh} to size of w
319
+ set output to output & pName & "||" & px & "," & py & "||" & sw & "," & sh & "\\n"
320
+ end repeat
321
+ end try
322
+ end repeat
323
+ end tell
324
+ return output'`);
325
+ return stdout.trim().split('\n').filter(Boolean).map(line => {
326
+ const [app, pos, sz] = line.split('||');
327
+ const [x, y] = (pos || '0,0').split(',').map(Number);
328
+ const [w, h] = (sz || '800,600').split(',').map(Number);
329
+ return { app, x, y, width: w, height: h };
330
+ });
331
+ }
332
+ return [];
333
+ } catch { return []; }
334
+ }
335
+
224
336
  async function openApp(appName) {
225
337
  const name = appName.toLowerCase();
226
338
  try {
@@ -312,6 +424,26 @@ async function handleCommand(msg) {
312
424
  case 'open_terminal':
313
425
  const termOk = await openTerminalWithChat(cmd.assistantName || cmd.name);
314
426
  return { ok: termOk };
427
+ case 'window_frontmost': {
428
+ const wf = await windowFrontmost();
429
+ return { ok: true, ...wf };
430
+ }
431
+ case 'window_move': {
432
+ const wm = await windowMove(cmd.app, cmd.x, cmd.y);
433
+ return { ok: wm };
434
+ }
435
+ case 'window_resize': {
436
+ const wr = await windowResize(cmd.app, cmd.w, cmd.h);
437
+ return { ok: wr };
438
+ }
439
+ case 'window_close': {
440
+ const wc = await windowClose(cmd.app);
441
+ return { ok: wc };
442
+ }
443
+ case 'window_list': {
444
+ const wl = await windowList();
445
+ return { ok: true, windows: wl };
446
+ }
315
447
  case 'ping':
316
448
  return { ok: true, pong: true };
317
449
  default: