ft-scout 8.0.2 → 8.0.4

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.
@@ -0,0 +1,390 @@
1
+ import { exec, spawn } from 'child_process';
2
+ import { promisify } from 'util';
3
+ import chalk from 'chalk';
4
+ import OpenAI from 'openai';
5
+ import dotenv from 'dotenv';
6
+ import { showScreenAuraOverlay, startScreenAuraOverlay, stopScreenAuraOverlay } from './appControl.js';
7
+ dotenv.config({ quiet: true });
8
+ const execAsync = promisify(exec);
9
+ /**
10
+ * Capture current active app window or desktop screen directly in memory as a compressed JPEG base64 string.
11
+ * When targetApp is specified (e.g. 'chrome', 'browser', 'code'), captures ONLY that application's window rectangle.
12
+ * Zero files are written to disk.
13
+ */
14
+ export async function captureLiveScreenFrameInMemory(targetApp) {
15
+ const platform = process.platform;
16
+ if (platform === 'win32') {
17
+ const cleanTarget = (targetApp || '').trim().replace(/"/g, '');
18
+ const psScript = `
19
+ Add-Type -AssemblyName System.Windows.Forms
20
+ Add-Type -AssemblyName System.Drawing
21
+ Add-Type -AssemblyName UIAutomationClient
22
+
23
+ $targetApp = "${cleanTarget}"
24
+ $screen = [System.Windows.Forms.Screen]::PrimaryScreen
25
+ $rect = $screen.Bounds
26
+ $activeTitle = "Desktop"
27
+ $isIsolated = $false
28
+
29
+ if ($targetApp) {
30
+ $procNames = @($targetApp)
31
+ if ($targetApp -match "browser|chrome|edge|web") {
32
+ $procNames = @("chrome", "msedge", "brave", "firefox")
33
+ } elseif ($targetApp -match "editor|code|vscode") {
34
+ $procNames = @("Code", "cursor", "notepad")
35
+ }
36
+
37
+ $proc = Get-Process -Name $procNames -ErrorAction SilentlyContinue | Where-Object { $_.MainWindowHandle -ne 0 } | Select-Object -First 1
38
+ if ($proc) {
39
+ $activeTitle = if ($proc.MainWindowTitle) { $proc.MainWindowTitle } else { $proc.ProcessName }
40
+ try {
41
+ $el = [System.Windows.Automation.AutomationElement]::FromHandle($proc.MainWindowHandle)
42
+ $b = $el.Current.BoundingRectangle
43
+ if ($b.Width -gt 80 -and $b.Height -gt 80) {
44
+ $rect = New-Object System.Drawing.Rectangle([int]$b.X, [int]$b.Y, [int]$b.Width, [int]$b.Height)
45
+ $isIsolated = $true
46
+ }
47
+ } catch {}
48
+ }
49
+ }
50
+
51
+ $bmp = New-Object System.Drawing.Bitmap($rect.Width, $rect.Height)
52
+ $g = [System.Drawing.Graphics]::FromImage($bmp)
53
+ try {
54
+ $g.CopyFromScreen($rect.Location, [System.Drawing.Point]::Empty, $rect.Size)
55
+ } catch {}
56
+
57
+ $ms = New-Object System.IO.MemoryStream
58
+ $bmp.Save($ms, [System.Drawing.Imaging.ImageFormat]::Jpeg)
59
+ $base64 = [System.Convert]::ToBase64String($ms.ToArray())
60
+ $cur = [System.Windows.Forms.Cursor]::Position
61
+
62
+ $g.Dispose()
63
+ $bmp.Dispose()
64
+ $ms.Dispose()
65
+
66
+ @{
67
+ width = $rect.Width
68
+ height = $rect.Height
69
+ cursorX = $cur.X
70
+ cursorY = $cur.Y
71
+ activeWindow = $activeTitle
72
+ targetApp = $targetApp
73
+ isIsolated = $isIsolated
74
+ base64 = $base64
75
+ } | ConvertTo-Json -Compress
76
+ `;
77
+ try {
78
+ const encoded = Buffer.from(psScript, 'utf16le').toString('base64');
79
+ const { stdout } = await execAsync(`powershell -NoProfile -EncodedCommand ${encoded}`, {
80
+ maxBuffer: 30 * 1024 * 1024,
81
+ timeout: 8000,
82
+ });
83
+ const parsed = JSON.parse(stdout.trim());
84
+ if (parsed && parsed.base64) {
85
+ return {
86
+ data: parsed.base64,
87
+ mimeType: 'image/jpeg',
88
+ width: Number(parsed.width) || 1920,
89
+ height: Number(parsed.height) || 1080,
90
+ timestamp: Date.now(),
91
+ activeWindow: String(parsed.activeWindow || 'Desktop'),
92
+ targetApp: parsed.targetApp || targetApp,
93
+ isAppIsolated: Boolean(parsed.isIsolated),
94
+ cursorPosition: {
95
+ x: Number(parsed.cursorX) || 0,
96
+ y: Number(parsed.cursorY) || 0,
97
+ },
98
+ };
99
+ }
100
+ }
101
+ catch {
102
+ return null;
103
+ }
104
+ }
105
+ else if (platform === 'darwin') {
106
+ try {
107
+ // macOS: capture directly to stdout as jpg
108
+ const { stdout } = await execAsync('screencapture -t jpg -x /dev/stdout', {
109
+ encoding: 'buffer',
110
+ maxBuffer: 20 * 1024 * 1024,
111
+ timeout: 5000,
112
+ });
113
+ if (stdout && stdout.length > 0) {
114
+ return {
115
+ data: Buffer.from(stdout).toString('base64'),
116
+ mimeType: 'image/jpeg',
117
+ width: 1920,
118
+ height: 1080,
119
+ timestamp: Date.now(),
120
+ activeWindow: 'Desktop',
121
+ cursorPosition: { x: 0, y: 0 },
122
+ };
123
+ }
124
+ }
125
+ catch {
126
+ return null;
127
+ }
128
+ }
129
+ else {
130
+ // Linux: capture to stdout using scrot or import
131
+ try {
132
+ const { stdout } = await execAsync('import -window root jpg:- || scrot -b -F -', {
133
+ encoding: 'buffer',
134
+ maxBuffer: 20 * 1024 * 1024,
135
+ timeout: 5000,
136
+ });
137
+ if (stdout && stdout.length > 0) {
138
+ return {
139
+ data: Buffer.from(stdout).toString('base64'),
140
+ mimeType: 'image/jpeg',
141
+ width: 1920,
142
+ height: 1080,
143
+ timestamp: Date.now(),
144
+ activeWindow: 'Desktop',
145
+ cursorPosition: { x: 0, y: 0 },
146
+ };
147
+ }
148
+ }
149
+ catch {
150
+ return null;
151
+ }
152
+ }
153
+ return null;
154
+ }
155
+ /**
156
+ * Call Vision AI directly with an in-memory base64 frame without writing anything to disk.
157
+ */
158
+ export async function callVisionAiWithFrame(frame, prompt, maxTokens = 350) {
159
+ if (!frame || !frame.data)
160
+ return null;
161
+ const nvidiaKey = process.env.NVIDIA_API_KEY || process.env.NVCF_API_KEY;
162
+ const geminiKey = process.env.GEMINI_API_KEY;
163
+ const openaiKey = process.env.OPENAI_API_KEY;
164
+ const byokKey = process.env.BYOK_API_KEY;
165
+ const candidates = [];
166
+ if (geminiKey) {
167
+ candidates.push({ apiKey: geminiKey, baseURL: 'https://generativelanguage.googleapis.com/v1beta/openai', model: 'gemini-2.0-flash', timeout: 20000 });
168
+ }
169
+ if (nvidiaKey) {
170
+ candidates.push({ apiKey: nvidiaKey, baseURL: 'https://integrate.api.nvidia.com/v1', model: 'meta/llama-3.2-11b-vision-instruct', timeout: 35000 });
171
+ }
172
+ if (openaiKey) {
173
+ candidates.push({ apiKey: openaiKey, model: 'gpt-4o-mini', timeout: 20000 });
174
+ }
175
+ if (byokKey) {
176
+ candidates.push({ apiKey: byokKey, model: 'gpt-4o-mini', timeout: 20000 });
177
+ }
178
+ for (const cand of candidates) {
179
+ try {
180
+ const client = new OpenAI({ apiKey: cand.apiKey, baseURL: cand.baseURL, timeout: cand.timeout });
181
+ const resp = await client.chat.completions.create({
182
+ model: cand.model,
183
+ messages: [
184
+ {
185
+ role: 'user',
186
+ content: [
187
+ { type: 'text', text: prompt },
188
+ { type: 'image_url', image_url: { url: `data:image/jpeg;base64,${frame.data}` } },
189
+ ],
190
+ },
191
+ ],
192
+ max_tokens: maxTokens,
193
+ });
194
+ const reply = resp.choices[0]?.message?.content?.trim();
195
+ if (reply) {
196
+ return reply;
197
+ }
198
+ }
199
+ catch {
200
+ continue;
201
+ }
202
+ }
203
+ return null;
204
+ }
205
+ /**
206
+ * Continuous Live Screen Share Session Manager.
207
+ * Maintains real-time screen stream in memory and shares frames directly with the AI model.
208
+ */
209
+ export class LiveScreenShareSession {
210
+ isStreaming = false;
211
+ timer = null;
212
+ latestFrame = null;
213
+ frameListeners = [];
214
+ streamStartTime = 0;
215
+ frameCount = 0;
216
+ targetApp = undefined;
217
+ isActive() {
218
+ return this.isStreaming;
219
+ }
220
+ setTargetApp(appName) {
221
+ this.targetApp = appName;
222
+ if (this.isStreaming) {
223
+ const appLabel = this.targetApp ? ` [App: ${this.targetApp}]` : '';
224
+ startScreenAuraOverlay(`Live Screen Share Active${appLabel} • Streaming to Model`).catch(() => { });
225
+ }
226
+ }
227
+ getTargetApp() {
228
+ return this.targetApp;
229
+ }
230
+ getLatestFrame() {
231
+ return this.latestFrame;
232
+ }
233
+ async getOrCaptureFrame() {
234
+ if (this.latestFrame && Date.now() - this.latestFrame.timestamp < 3000) {
235
+ return this.latestFrame;
236
+ }
237
+ const fresh = await captureLiveScreenFrameInMemory(this.targetApp);
238
+ if (fresh) {
239
+ this.latestFrame = fresh;
240
+ }
241
+ return this.latestFrame;
242
+ }
243
+ async start(options) {
244
+ if (this.isStreaming) {
245
+ return { success: true, message: 'Live screen sharing is already active.' };
246
+ }
247
+ this.isStreaming = true;
248
+ this.streamStartTime = Date.now();
249
+ this.frameCount = 0;
250
+ if (options?.targetApp) {
251
+ this.targetApp = options.targetApp;
252
+ }
253
+ if (options?.onFrame) {
254
+ this.frameListeners.push(options.onFrame);
255
+ }
256
+ // Show live visual screen share aura HUD continuously while screen sharing is running
257
+ const appLabel = this.targetApp ? ` [App: ${this.targetApp}]` : '';
258
+ startScreenAuraOverlay(`Live Screen Share Active${appLabel} • Streaming to Model`).catch(() => { });
259
+ console.log(chalk.bold.red('\n[LIVE SCREEN SHARE ACTIVE]') + chalk.cyan(` Real-time screen feed is streaming directly to the model (0 files saved to disk).${appLabel ? ` Focused window: ${this.targetApp}` : ''}`));
260
+ // Capture initial frame immediately
261
+ const initFrame = await captureLiveScreenFrameInMemory(this.targetApp);
262
+ if (initFrame) {
263
+ this.latestFrame = initFrame;
264
+ this.frameCount++;
265
+ this.notifyListeners(initFrame);
266
+ }
267
+ const intervalMs = Math.max(1000, options?.intervalMs || 2000);
268
+ this.timer = setInterval(async () => {
269
+ if (!this.isStreaming)
270
+ return;
271
+ try {
272
+ const frame = await captureLiveScreenFrameInMemory(this.targetApp);
273
+ if (frame) {
274
+ this.latestFrame = frame;
275
+ this.frameCount++;
276
+ this.notifyListeners(frame);
277
+ }
278
+ }
279
+ catch { }
280
+ }, intervalMs);
281
+ return {
282
+ success: true,
283
+ message: `Live screen share initiated. ${this.targetApp ? `Only the ${this.targetApp} window is being shared.` : 'Screen is streaming to model in real time.'}`,
284
+ };
285
+ }
286
+ stop() {
287
+ if (!this.isStreaming) {
288
+ return { success: true, summary: 'Live screen share was not running.' };
289
+ }
290
+ this.isStreaming = false;
291
+ if (this.timer) {
292
+ clearInterval(this.timer);
293
+ this.timer = null;
294
+ }
295
+ this.frameListeners = [];
296
+ // Close persistent screen share aura overlay
297
+ stopScreenAuraOverlay();
298
+ const elapsedSecs = Math.round((Date.now() - this.streamStartTime) / 1000);
299
+ const summary = `Live screen share session ended. Streamed ${this.frameCount} frames over ${elapsedSecs}s in-memory.`;
300
+ console.log(chalk.yellow(`\n⚪ [LIVE SCREEN SHARE STOPPED] ${summary}`));
301
+ return { success: true, summary };
302
+ }
303
+ onFrame(callback) {
304
+ this.frameListeners.push(callback);
305
+ return () => {
306
+ this.frameListeners = this.frameListeners.filter((cb) => cb !== callback);
307
+ };
308
+ }
309
+ notifyListeners(frame) {
310
+ for (const listener of this.frameListeners) {
311
+ try {
312
+ listener(frame);
313
+ }
314
+ catch { }
315
+ }
316
+ }
317
+ /**
318
+ * Inspect active live screen share stream directly in memory.
319
+ */
320
+ async analyzeLiveStream(targetQuery) {
321
+ const frame = await this.getOrCaptureFrame();
322
+ if (!frame) {
323
+ return {
324
+ success: false,
325
+ output: 'Could not capture frame from live screen stream.',
326
+ };
327
+ }
328
+ let aiVision = '';
329
+ try {
330
+ const prompt = targetQuery
331
+ ? `Analyze this live screen stream frame specifically regarding: "${targetQuery}". Keep it concise, noting active window, visible UI elements, buttons, or error messages.`
332
+ : `Briefly describe what is currently visible on this live application/screen stream: active window, main content/tabs, and system state in 2-3 sentences.`;
333
+ const reply = await callVisionAiWithFrame(frame, prompt, 350);
334
+ if (reply) {
335
+ aiVision = `\nScout Live Screen Stream Analysis:\n${reply.trim()}`;
336
+ }
337
+ }
338
+ catch { }
339
+ const isolationLabel = frame.isAppIsolated
340
+ ? `YES (Focused ONLY on "${frame.targetApp || frame.activeWindow}" window)`
341
+ : `Full Desktop (${frame.targetApp ? `Waiting for ${frame.targetApp} window to focus` : 'Default'})`;
342
+ const report = [
343
+ `=== SCOUT LIVE SCREEN SHARE FEED ===`,
344
+ `Status: Live Stream Active`,
345
+ `Target App: ${frame.targetApp || 'All Active Windows'}`,
346
+ `App Isolation: ${isolationLabel}`,
347
+ `Resolution: ${frame.width}x${frame.height}`,
348
+ `Active Window: "${frame.activeWindow}"`,
349
+ `Mouse Cursor: (${frame.cursorPosition.x}, ${frame.cursorPosition.y})`,
350
+ `Capture Mode: In-Memory Live Video Stream (Zero disk I/O / No screenshot files created)`,
351
+ `Live Feed Status: Screen is actively shared with the model in real time.${aiVision}`,
352
+ ].join('\n');
353
+ return {
354
+ success: true,
355
+ output: report,
356
+ details: {
357
+ width: frame.width,
358
+ height: frame.height,
359
+ activeWindow: frame.activeWindow,
360
+ targetApp: frame.targetApp,
361
+ isAppIsolated: frame.isAppIsolated,
362
+ cursorPosition: frame.cursorPosition,
363
+ timestamp: frame.timestamp,
364
+ },
365
+ };
366
+ }
367
+ }
368
+ export const globalScreenShareSession = new LiveScreenShareSession();
369
+ export async function startLiveScreenShare(options) {
370
+ return await globalScreenShareSession.start(options);
371
+ }
372
+ export function stopLiveScreenShare() {
373
+ return globalScreenShareSession.stop();
374
+ }
375
+ export function isLiveScreenShareActive() {
376
+ return globalScreenShareSession.isActive();
377
+ }
378
+ export async function getLiveScreenFrame() {
379
+ return await globalScreenShareSession.getOrCaptureFrame();
380
+ }
381
+ export async function analyzeLiveScreen(targetQuery) {
382
+ return await globalScreenShareSession.analyzeLiveStream(targetQuery);
383
+ }
384
+ export function setLiveScreenTargetApp(appName) {
385
+ globalScreenShareSession.setTargetApp(appName);
386
+ }
387
+ export function getLiveScreenTargetApp() {
388
+ return globalScreenShareSession.getTargetApp();
389
+ }
390
+ //# sourceMappingURL=liveScreenEngine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"liveScreenEngine.js","sourceRoot":"","sources":["liveScreenEngine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,248 @@
1
+ param(
2
+ [string]$OutPath,
3
+ [switch]$InfoOnly
4
+ )
5
+
6
+ $source = @"
7
+ using System;
8
+ using System.Drawing;
9
+ using System.Drawing.Imaging;
10
+ using System.Runtime.InteropServices;
11
+ using System.Text;
12
+ using System.Threading;
13
+ using System.Collections.Generic;
14
+
15
+ public class WinCaptureResult {
16
+ public bool success;
17
+ public string savedPath;
18
+ public int width;
19
+ public int height;
20
+ public int cursorX;
21
+ public int cursorY;
22
+ public string activeWindow;
23
+ public string[] visibleWindows;
24
+ public string error;
25
+ }
26
+
27
+ public class WinCaptureHelper {
28
+ [DllImport("user32.dll", SetLastError = true)]
29
+ public static extern IntPtr OpenInputDesktop(uint dwFlags, bool fInherit, uint dwDesiredAccess);
30
+
31
+ [DllImport("user32.dll", SetLastError = true)]
32
+ public static extern IntPtr OpenDesktop(string lpszDesktop, uint dwFlags, bool fInherit, uint dwDesiredAccess);
33
+
34
+ [DllImport("user32.dll", SetLastError = true)]
35
+ public static extern bool SetThreadDesktop(IntPtr hDesktop);
36
+
37
+ [DllImport("user32.dll", SetLastError = true)]
38
+ public static extern bool CloseDesktop(IntPtr hDesktop);
39
+
40
+ [DllImport("user32.dll")]
41
+ public static extern IntPtr GetDC(IntPtr hWnd);
42
+
43
+ [DllImport("user32.dll")]
44
+ public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
45
+
46
+ [DllImport("gdi32.dll")]
47
+ public static extern IntPtr CreateCompatibleDC(IntPtr hdc);
48
+
49
+ [DllImport("gdi32.dll")]
50
+ public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);
51
+
52
+ [DllImport("gdi32.dll")]
53
+ public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
54
+
55
+ [DllImport("gdi32.dll")]
56
+ public static extern bool DeleteDC(IntPtr hdc);
57
+
58
+ [DllImport("gdi32.dll")]
59
+ public static extern bool DeleteObject(IntPtr hObject);
60
+
61
+ [DllImport("gdi32.dll")]
62
+ public static extern bool BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, int dwRop);
63
+
64
+ [DllImport("user32.dll")]
65
+ public static extern int GetSystemMetrics(int nIndex);
66
+
67
+ public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
68
+
69
+ [DllImport("user32.dll")]
70
+ public static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
71
+
72
+ [DllImport("user32.dll", CharSet = CharSet.Auto)]
73
+ public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
74
+
75
+ [DllImport("user32.dll")]
76
+ public static extern bool IsWindowVisible(IntPtr hWnd);
77
+
78
+ [DllImport("user32.dll")]
79
+ public static extern IntPtr GetForegroundWindow();
80
+
81
+ [StructLayout(LayoutKind.Sequential)]
82
+ public struct POINT {
83
+ public int X;
84
+ public int Y;
85
+ }
86
+
87
+ [DllImport("user32.dll")]
88
+ public static extern bool GetCursorPos(out POINT lpPoint);
89
+
90
+ const uint DESKTOP_ACCESS = 0x01FF | 0x00020000;
91
+ const int SM_CXSCREEN = 0;
92
+ const int SM_CYSCREEN = 1;
93
+ const int SRCCOPY = 0x00CC0020;
94
+ const int CAPTUREBLT = 0x40000000;
95
+
96
+ public static WinCaptureResult GetInfo() {
97
+ var res = new WinCaptureResult();
98
+ res.success = true;
99
+ res.error = "";
100
+ var visibleWindows = new List<string>();
101
+
102
+ Thread worker = new Thread(() => {
103
+ IntPtr hDesk = OpenInputDesktop(0, false, DESKTOP_ACCESS);
104
+ if (hDesk == IntPtr.Zero) {
105
+ hDesk = OpenDesktop("Default", 0, false, DESKTOP_ACCESS);
106
+ }
107
+ if (hDesk != IntPtr.Zero) {
108
+ SetThreadDesktop(hDesk);
109
+ }
110
+
111
+ res.width = GetSystemMetrics(SM_CXSCREEN);
112
+ res.height = GetSystemMetrics(SM_CYSCREEN);
113
+ if (res.width <= 0) res.width = 1920;
114
+ if (res.height <= 0) res.height = 1080;
115
+
116
+ POINT pt;
117
+ if (GetCursorPos(out pt)) {
118
+ res.cursorX = pt.X;
119
+ res.cursorY = pt.Y;
120
+ }
121
+
122
+ IntPtr fg = GetForegroundWindow();
123
+ if (fg != IntPtr.Zero) {
124
+ var sbFg = new StringBuilder(256);
125
+ GetWindowText(fg, sbFg, 256);
126
+ res.activeWindow = sbFg.ToString().Trim();
127
+ } else {
128
+ res.activeWindow = "";
129
+ }
130
+
131
+ EnumWindows((hWnd, lParam) => {
132
+ if (IsWindowVisible(hWnd)) {
133
+ var title = new StringBuilder(256);
134
+ GetWindowText(hWnd, title, 256);
135
+ string t = title.ToString().Trim();
136
+ if (t.Length > 0 && !visibleWindows.Contains(t) && t != "Program Manager" && t != "Windows Input Experience") {
137
+ visibleWindows.Add(t);
138
+ }
139
+ }
140
+ return true;
141
+ }, IntPtr.Zero);
142
+
143
+ if (hDesk != IntPtr.Zero) {
144
+ CloseDesktop(hDesk);
145
+ }
146
+ });
147
+
148
+ worker.SetApartmentState(ApartmentState.STA);
149
+ worker.Start();
150
+ worker.Join();
151
+
152
+ res.visibleWindows = visibleWindows.ToArray();
153
+ return res;
154
+ }
155
+
156
+ public static WinCaptureResult Capture(string filePath) {
157
+ var res = new WinCaptureResult();
158
+ res.savedPath = filePath;
159
+ res.error = "";
160
+ var visibleWindows = new List<string>();
161
+
162
+ Thread worker = new Thread(() => {
163
+ IntPtr hDesk = OpenInputDesktop(0, false, DESKTOP_ACCESS);
164
+ if (hDesk == IntPtr.Zero) {
165
+ hDesk = OpenDesktop("Default", 0, false, DESKTOP_ACCESS);
166
+ }
167
+ if (hDesk != IntPtr.Zero) {
168
+ SetThreadDesktop(hDesk);
169
+ }
170
+
171
+ res.width = GetSystemMetrics(SM_CXSCREEN);
172
+ res.height = GetSystemMetrics(SM_CYSCREEN);
173
+ if (res.width <= 0) res.width = 1920;
174
+ if (res.height <= 0) res.height = 1080;
175
+
176
+ POINT pt;
177
+ if (GetCursorPos(out pt)) {
178
+ res.cursorX = pt.X;
179
+ res.cursorY = pt.Y;
180
+ }
181
+
182
+ IntPtr fg = GetForegroundWindow();
183
+ if (fg != IntPtr.Zero) {
184
+ var sbFg = new StringBuilder(256);
185
+ GetWindowText(fg, sbFg, 256);
186
+ res.activeWindow = sbFg.ToString().Trim();
187
+ } else {
188
+ res.activeWindow = "";
189
+ }
190
+
191
+ EnumWindows((hWnd, lParam) => {
192
+ if (IsWindowVisible(hWnd)) {
193
+ var title = new StringBuilder(256);
194
+ GetWindowText(hWnd, title, 256);
195
+ string t = title.ToString().Trim();
196
+ if (t.Length > 0 && !visibleWindows.Contains(t) && t != "Program Manager" && t != "Windows Input Experience") {
197
+ visibleWindows.Add(t);
198
+ }
199
+ }
200
+ return true;
201
+ }, IntPtr.Zero);
202
+
203
+ try {
204
+ IntPtr hdcSrc = GetDC(IntPtr.Zero);
205
+ IntPtr hdcDest = CreateCompatibleDC(hdcSrc);
206
+ IntPtr hBitmap = CreateCompatibleBitmap(hdcSrc, res.width, res.height);
207
+ IntPtr hOld = SelectObject(hdcDest, hBitmap);
208
+ bool bltOk = BitBlt(hdcDest, 0, 0, res.width, res.height, hdcSrc, 0, 0, SRCCOPY | CAPTUREBLT);
209
+
210
+ SelectObject(hdcDest, hOld);
211
+ DeleteDC(hdcDest);
212
+ ReleaseDC(IntPtr.Zero, hdcSrc);
213
+
214
+ if (bltOk) {
215
+ using (Bitmap bmp = Bitmap.FromHbitmap(hBitmap)) {
216
+ bmp.Save(filePath, ImageFormat.Png);
217
+ }
218
+ res.success = true;
219
+ } else {
220
+ res.error = "BitBlt failed";
221
+ }
222
+ DeleteObject(hBitmap);
223
+ } catch (Exception ex) {
224
+ res.error = ex.Message;
225
+ }
226
+
227
+ if (hDesk != IntPtr.Zero) {
228
+ CloseDesktop(hDesk);
229
+ }
230
+ });
231
+
232
+ worker.SetApartmentState(ApartmentState.STA);
233
+ worker.Start();
234
+ worker.Join();
235
+
236
+ res.visibleWindows = visibleWindows.ToArray();
237
+ return res;
238
+ }
239
+ }
240
+ "@
241
+
242
+ Add-Type -TypeDefinition $source -ReferencedAssemblies System.Drawing, System.Windows.Forms
243
+
244
+ if ($InfoOnly) {
245
+ [WinCaptureHelper]::GetInfo() | ConvertTo-Json -Compress
246
+ } else {
247
+ [WinCaptureHelper]::Capture($OutPath) | ConvertTo-Json -Compress
248
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"voiceEngine.d.ts","sourceRoot":"","sources":["voiceEngine.ts"],"names":[],"mappings":"AAOA,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,CAcvE;AAED,MAAM,WAAW,YAAY;IACzB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASvD;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA2CnF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAoEpF"}
1
+ {"version":3,"file":"voiceEngine.d.ts","sourceRoot":"","sources":["voiceEngine.ts"],"names":[],"mappings":"AAOA,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,MAAM,GAAG,OAAO,GAAG,cAAc,CAAC,CAexF;AAED,MAAM,WAAW,YAAY;IACzB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASvD;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA2CnF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAoEpF"}
@@ -10,6 +10,7 @@ export async function promptInteractionMode() {
10
10
  options: [
11
11
  { value: 'text', label: 'Text Interaction', hint: 'Text command input -> Text response' },
12
12
  { value: 'audio', label: 'Audio Interaction', hint: 'Voice command input (STT) -> Text + Voice response (TTS)' },
13
+ { value: 'screen_share', label: 'Live Screen Share Interaction', hint: 'Real-time live screen share stream to model + Voice & Text' },
13
14
  ],
14
15
  });
15
16
  if (isCancel(choice))