mindweave 3.2.2 → 3.2.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.
Files changed (59) hide show
  1. package/dist/cli/App.js +37 -7
  2. package/dist/cli/App.js.map +1 -1
  3. package/dist/cli/agentLines.js +196 -0
  4. package/dist/cli/agentLines.js.map +1 -0
  5. package/dist/cli/approvalText.js +31 -0
  6. package/dist/cli/approvalText.js.map +1 -0
  7. package/dist/cli/components/BlockView.js +1 -1
  8. package/dist/cli/components/BlockView.js.map +1 -1
  9. package/dist/cli/components/SubagentView.js +43 -74
  10. package/dist/cli/components/SubagentView.js.map +1 -1
  11. package/dist/cli/components/WorkGroup.js +1 -1
  12. package/dist/cli/components/WorkGroup.js.map +1 -1
  13. package/dist/cli/help.js +3 -1
  14. package/dist/cli/help.js.map +1 -1
  15. package/dist/cli/transcript.js +13 -3
  16. package/dist/cli/transcript.js.map +1 -1
  17. package/dist/core/turnRunner.js +2 -2
  18. package/dist/core/turnRunner.js.map +1 -1
  19. package/dist/dynamo/engine.js +28 -4
  20. package/dist/dynamo/engine.js.map +1 -1
  21. package/dist/dynamo/guard.js +6 -0
  22. package/dist/dynamo/guard.js.map +1 -1
  23. package/dist/dynamo/marathon.js +22 -4
  24. package/dist/dynamo/marathon.js.map +1 -1
  25. package/dist/memory/compaction.js +60 -6
  26. package/dist/memory/compaction.js.map +1 -1
  27. package/dist/memory/session.js +2 -0
  28. package/dist/memory/session.js.map +1 -1
  29. package/dist/tools/childReport.js +44 -0
  30. package/dist/tools/childReport.js.map +1 -0
  31. package/dist/tools/guard.js +9 -2
  32. package/dist/tools/guard.js.map +1 -1
  33. package/dist/tools/registry.js +1 -1
  34. package/dist/tools/registry.js.map +1 -1
  35. package/dist/tools/runCommand.js +92 -56
  36. package/dist/tools/runCommand.js.map +1 -1
  37. package/dist/tools/screenshot.js +28 -9
  38. package/dist/tools/screenshot.js.map +1 -1
  39. package/dist/tools/screenshotWin.js +258 -175
  40. package/dist/tools/screenshotWin.js.map +1 -1
  41. package/dist/tools/subagent.js +73 -31
  42. package/dist/tools/subagent.js.map +1 -1
  43. package/dist/tools/subagentOutcome.js +27 -0
  44. package/dist/tools/subagentOutcome.js.map +1 -0
  45. package/dist/tools/treeGuard.js +164 -0
  46. package/dist/tools/treeGuard.js.map +1 -0
  47. package/dist/tools/ui.js +32 -1
  48. package/dist/tools/ui.js.map +1 -1
  49. package/dist/tools/uiHide.js +19 -6
  50. package/dist/tools/uiHide.js.map +1 -1
  51. package/dist/tools/verifierCommands.js +188 -0
  52. package/dist/tools/verifierCommands.js.map +1 -0
  53. package/dist/tools/verifierRun.js +88 -0
  54. package/dist/tools/verifierRun.js.map +1 -0
  55. package/dist/tools/verifierTools.js +19 -0
  56. package/dist/tools/verifierTools.js.map +1 -0
  57. package/dist/tools/verifyReport.js +79 -9
  58. package/dist/tools/verifyReport.js.map +1 -1
  59. package/package.json +3 -3
@@ -42,176 +42,221 @@ import { tmpdir } from "node:os";
42
42
  import { join } from "node:path";
43
43
  import { DESK_CS, HIDDEN_MARK, hiddenDesktopName, windowArgs } from "./hiddenDesktop.js";
44
44
  const PS_TIMEOUT_MS = 20_000;
45
- const SCRIPT = String.raw `
46
- param([string]$Mode = "list", [string]$Handle = "", [string]$Out = "", [string]$Desktop = "", [string]$Hidden = "")
47
- $ErrorActionPreference = "Stop"
48
- Add-Type -AssemblyName System.Drawing
49
-
50
- Add-Type -ReferencedAssemblies System.Drawing -TypeDefinition @"
51
- using System;
52
- using System.Collections.Generic;
53
- using System.Drawing;
54
- using System.Drawing.Imaging;
55
- using System.Runtime.InteropServices;
56
- using System.Text;
57
-
58
- public static class MwCapture {
59
- delegate bool EnumProc(IntPtr hWnd, IntPtr lParam);
60
- [DllImport("user32.dll")] static extern bool EnumWindows(EnumProc cb, IntPtr l);
61
- [DllImport("user32.dll")] static extern bool IsWindowVisible(IntPtr h);
62
- [DllImport("user32.dll")] static extern bool IsIconic(IntPtr h);
63
- [DllImport("user32.dll", CharSet = CharSet.Unicode)] static extern int GetWindowTextLength(IntPtr h);
64
- [DllImport("user32.dll", CharSet = CharSet.Unicode)] static extern int GetWindowText(IntPtr h, StringBuilder s, int n);
65
- [DllImport("user32.dll")] static extern bool PrintWindow(IntPtr h, IntPtr hdc, uint flags);
66
- [DllImport("user32.dll")] static extern bool SetProcessDPIAware();
67
- [DllImport("user32.dll")] static extern bool GetWindowRect(IntPtr h, out RECT r);
68
- [DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow();
69
- [DllImport("user32.dll")] static extern uint GetWindowThreadProcessId(IntPtr h, out uint pid);
70
- [DllImport("user32.dll")] static extern int GetWindowLong(IntPtr h, int index);
71
- [DllImport("dwmapi.dll")] static extern int DwmGetWindowAttribute(IntPtr h, int attr, out RECT r, int size);
72
- [DllImport("dwmapi.dll", EntryPoint = "DwmGetWindowAttribute")] static extern int DwmGetIntAttribute(IntPtr h, int attr, out int v, int size);
73
-
74
- [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left, Top, Right, Bottom; }
75
-
76
- public static void Dpi() { SetProcessDPIAware(); }
77
-
78
- // A DWM-cloaked window passes IsWindowVisible but is not actually on screen — the
79
- // invisible UWP and host windows that would otherwise flood the list. Any failure to
80
- // read the attribute is treated as not-cloaked, so a window is never dropped on error.
81
- static bool Cloaked(IntPtr h) {
82
- int v;
83
- return DwmGetIntAttribute(h, 14 /* DWMWA_CLOAKED */, out v, sizeof(int)) == 0 && v != 0;
84
- }
85
-
86
- // The Shell's own "is this an Alt-Tab window" test: a tool window is a palette or
87
- // tray surface and is never what "the app" means, unless it also asks for the taskbar.
88
- static bool AltTabWorthy(IntPtr h) {
89
- int ex = GetWindowLong(h, -20 /* GWL_EXSTYLE */);
90
- bool tool = (ex & 0x00000080) != 0; // WS_EX_TOOLWINDOW
91
- bool app = (ex & 0x00040000) != 0; // WS_EX_APPWINDOW
92
- return !tool || app;
93
- }
94
-
95
- // The window's process name, for a window that has no title of its own. Wrapped
96
- // because the process can exit between the enum and the lookup.
97
- static string ProcName(IntPtr h) {
98
- try {
99
- uint pid;
100
- GetWindowThreadProcessId(h, out pid);
101
- if (pid == 0) return "";
102
- using (var p = System.Diagnostics.Process.GetProcessById((int)pid)) return p.ProcessName;
103
- } catch { return ""; }
104
- }
105
-
106
- // DWMWA_EXTENDED_FRAME_BOUNDS. GetWindowRect includes an invisible border on
107
- // Windows 10+, so it is the fallback rather than the first choice.
108
- static bool Bounds(IntPtr h, out RECT r) {
109
- if (DwmGetWindowAttribute(h, 9, out r, Marshal.SizeOf(typeof(RECT))) == 0
110
- && r.Right > r.Left && r.Bottom > r.Top) return true;
111
- return GetWindowRect(h, out r);
112
- }
113
-
114
- // The hidden desktop's windows are marked, so a capture is sent back there.
115
- public static string ListOn(string desk) {
116
- return MwDesk.On(desk, () => string.Join("\n", List("${HIDDEN_MARK}").ToArray()));
117
- }
118
-
119
- public static List<string> List(string mark) {
120
- var found = new List<string>();
121
- IntPtr fg = GetForegroundWindow();
122
- EnumWindows(delegate(IntPtr h, IntPtr l) {
123
- if (!IsWindowVisible(h) || IsIconic(h)) return true;
124
- if (Cloaked(h) || !AltTabWorthy(h)) return true;
125
- RECT r;
126
- if (!Bounds(h, out r)) return true;
127
- // Tool windows and tray hosts are real but never what anyone means.
128
- if (r.Right - r.Left < 120 || r.Bottom - r.Top < 120) return true;
129
- int len = GetWindowTextLength(h);
130
- string title = "";
131
- if (len > 0) {
132
- var sb = new StringBuilder(len + 1);
133
- GetWindowText(h, sb, sb.Capacity);
134
- title = sb.ToString().Trim();
135
- }
136
- // An empty title is NOT a reason to drop the window. A custom title bar
137
- // (Tauri or Electron with decorations off) leaves the OS title blank, as does
138
- // an app whose web content has not set document.title yet — and dropping it
139
- // makes a window the user is plainly looking at impossible to capture, by name
140
- // OR as the foreground. Label it by its process so it stays nameable.
141
- if (title.Length == 0) {
142
- string pn = ProcName(h);
143
- title = pn.Length > 0 ? pn : "(untitled window)";
144
- }
145
- // The leading marker is how the caller knows which window the user is
146
- // actually looking at, so it can name it when asking permission.
147
- found.Add((h == fg && mark.Length == 0 ? "*" : "-") + mark + h.ToInt64().ToString() + "\t" + title);
148
- return true;
149
- }, IntPtr.Zero);
150
- return found;
151
- }
152
-
153
- public static string CaptureOn(string desk, IntPtr h, string path) {
154
- return MwDesk.On(desk, () => Capture(h, path, string.IsNullOrEmpty(desk)));
155
- }
156
-
157
- // screen: whether a blank PrintWindow may fall back to copying the screen. Never for a
158
- // window on the hidden desktop: the screen is the USER's, and that window is not on it.
159
- public static string Capture(IntPtr h, string path, bool screen) {
160
- RECT r;
161
- if (!Bounds(h, out r)) return "ERR could not measure the window";
162
- int w = r.Right - r.Left, ht = r.Bottom - r.Top;
163
- if (w <= 0 || ht <= 0) return "ERR the window has no visible area";
164
- using (var bmp = new Bitmap(w, ht)) {
165
- bool drew = false;
166
- using (var g = Graphics.FromImage(bmp)) {
167
- IntPtr hdc = g.GetHdc();
168
- drew = PrintWindow(h, hdc, 2); // PW_RENDERFULLCONTENT
169
- g.ReleaseHdc(hdc);
170
- }
171
- if (!drew || Blank(bmp)) {
172
- if (!screen) return "ERR the window drew nothing to capture";
173
- using (var g = Graphics.FromImage(bmp)) {
174
- g.CopyFromScreen(r.Left, r.Top, 0, 0, new Size(w, ht));
175
- }
176
- }
177
- bmp.Save(path, ImageFormat.Png);
178
- return "OK " + w + " " + ht;
179
- }
180
- }
181
-
182
- // PrintWindow can report success and draw nothing. Sampling three corners of a
183
- // fully transparent bitmap is enough to tell that apart from a real capture.
184
- static bool Blank(Bitmap b) {
185
- if (b.Width < 4 || b.Height < 4) return false;
186
- return b.GetPixel(1, 1).A == 0
187
- && b.GetPixel(b.Width / 2, b.Height / 2).A == 0
188
- && b.GetPixel(b.Width - 2, b.Height - 2).A == 0;
189
- }
190
- }
191
- ${DESK_CS}
192
- "@
193
-
194
- # Before any measurement, or every rectangle is in the wrong coordinate space.
195
- [MwCapture]::Dpi() | Out-Null
196
-
197
- if ($Mode -eq "list") {
198
- [MwCapture]::List("") | ForEach-Object { Write-Output $_ }
199
- # The windows of apps started for testing, which are never on the screen.
200
- if ($Hidden -and [MwDesk]::Exists($Hidden)) { Write-Output ([MwCapture]::ListOn($Hidden)) }
201
- exit 0
202
- }
203
-
204
- if ($Mode -eq "capture") {
205
- $h = if ($Handle -eq "foreground") { [MwCapture]::GetForegroundWindow() } else { [IntPtr][Int64]$Handle }
206
- if ($h -eq [IntPtr]::Zero) { Write-Output "ERR no such window"; exit 1 }
207
- $r = [MwCapture]::CaptureOn($Desktop, $h, $Out)
208
- Write-Output $r
209
- if ($r.StartsWith("ERR")) { exit 1 }
210
- exit 0
211
- }
212
-
213
- Write-Output "ERR unknown mode"
214
- exit 1
45
+ const SCRIPT = String.raw `
46
+ param([string]$Mode = "list", [string]$Handle = "", [string]$Out = "", [string]$Desktop = "", [string]$Hidden = "", [int]$Owner = 0)
47
+ $ErrorActionPreference = "Stop"
48
+ Add-Type -AssemblyName System.Drawing
49
+
50
+ Add-Type -ReferencedAssemblies System.Drawing -TypeDefinition @"
51
+ using System;
52
+ using System.Collections.Generic;
53
+ using System.Drawing;
54
+ using System.Drawing.Imaging;
55
+ using System.Runtime.InteropServices;
56
+ using System.Text;
57
+
58
+ public static class MwCapture {
59
+ // The processes this one runs inside (the terminal, its console host, the app hosting it).
60
+ // Their windows are marked "host" in the list, so the caller can tell them from the app under test.
61
+ public static HashSet<uint> HostPids = new HashSet<uint>();
62
+ delegate bool EnumProc(IntPtr hWnd, IntPtr lParam);
63
+ [DllImport("user32.dll")] static extern bool EnumWindows(EnumProc cb, IntPtr l);
64
+ [DllImport("user32.dll")] static extern bool IsWindowVisible(IntPtr h);
65
+ [DllImport("user32.dll")] static extern bool IsIconic(IntPtr h);
66
+ [DllImport("user32.dll", CharSet = CharSet.Unicode)] static extern int GetWindowTextLength(IntPtr h);
67
+ [DllImport("user32.dll", CharSet = CharSet.Unicode)] static extern int GetWindowText(IntPtr h, StringBuilder s, int n);
68
+ [DllImport("user32.dll")] static extern bool PrintWindow(IntPtr h, IntPtr hdc, uint flags);
69
+ [DllImport("user32.dll")] static extern bool SetProcessDPIAware();
70
+ [DllImport("user32.dll")] static extern bool GetWindowRect(IntPtr h, out RECT r);
71
+ [DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow();
72
+ [DllImport("user32.dll")] static extern uint GetWindowThreadProcessId(IntPtr h, out uint pid);
73
+ [DllImport("user32.dll")] static extern int GetWindowLong(IntPtr h, int index);
74
+ [DllImport("dwmapi.dll")] static extern int DwmGetWindowAttribute(IntPtr h, int attr, out RECT r, int size);
75
+ [DllImport("dwmapi.dll", EntryPoint = "DwmGetWindowAttribute")] static extern int DwmGetIntAttribute(IntPtr h, int attr, out int v, int size);
76
+
77
+ [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left, Top, Right, Bottom; }
78
+
79
+ public static void Dpi() { SetProcessDPIAware(); }
80
+
81
+ [DllImport("kernel32.dll")] static extern IntPtr GetConsoleWindow();
82
+ [DllImport("user32.dll")] static extern IntPtr GetAncestor(IntPtr h, uint flags);
83
+
84
+ // The window the console this process is attached to is drawn in. In Windows Terminal the console
85
+ // window is a hidden stand-in owned by the real top-level window, so the owner is what is returned.
86
+ // Empty when there is no console (the desktop app, a service).
87
+ public static string HostWindow() {
88
+ IntPtr c = GetConsoleWindow();
89
+ if (c == IntPtr.Zero) return "";
90
+ IntPtr root = GetAncestor(c, 3 /* GA_ROOTOWNER */);
91
+ return (root == IntPtr.Zero ? c : root).ToInt64().ToString();
92
+ }
93
+
94
+ // A DWM-cloaked window passes IsWindowVisible but is not actually on screen — the
95
+ // invisible UWP and host windows that would otherwise flood the list. Any failure to
96
+ // read the attribute is treated as not-cloaked, so a window is never dropped on error.
97
+ static bool Cloaked(IntPtr h) {
98
+ int v;
99
+ return DwmGetIntAttribute(h, 14 /* DWMWA_CLOAKED */, out v, sizeof(int)) == 0 && v != 0;
100
+ }
101
+
102
+ // The Shell's own "is this an Alt-Tab window" test: a tool window is a palette or
103
+ // tray surface and is never what "the app" means, unless it also asks for the taskbar.
104
+ static bool AltTabWorthy(IntPtr h) {
105
+ int ex = GetWindowLong(h, -20 /* GWL_EXSTYLE */);
106
+ bool tool = (ex & 0x00000080) != 0; // WS_EX_TOOLWINDOW
107
+ bool app = (ex & 0x00040000) != 0; // WS_EX_APPWINDOW
108
+ return !tool || app;
109
+ }
110
+
111
+ // The window's process name, for a window that has no title of its own. Wrapped
112
+ // because the process can exit between the enum and the lookup.
113
+ static string ProcName(IntPtr h) {
114
+ try {
115
+ uint pid;
116
+ GetWindowThreadProcessId(h, out pid);
117
+ if (pid == 0) return "";
118
+ using (var p = System.Diagnostics.Process.GetProcessById((int)pid)) return p.ProcessName;
119
+ } catch { return ""; }
120
+ }
121
+
122
+ // DWMWA_EXTENDED_FRAME_BOUNDS. GetWindowRect includes an invisible border on
123
+ // Windows 10+, so it is the fallback rather than the first choice.
124
+ static bool Bounds(IntPtr h, out RECT r) {
125
+ if (DwmGetWindowAttribute(h, 9, out r, Marshal.SizeOf(typeof(RECT))) == 0
126
+ && r.Right > r.Left && r.Bottom > r.Top) return true;
127
+ return GetWindowRect(h, out r);
128
+ }
129
+
130
+ // The hidden desktop's windows are marked, so a capture is sent back there.
131
+ public static string ListOn(string desk) {
132
+ return MwDesk.On(desk, () => string.Join("\n", List("${HIDDEN_MARK}").ToArray()));
133
+ }
134
+
135
+ public static List<string> List(string mark) {
136
+ var found = new List<string>();
137
+ IntPtr fg = GetForegroundWindow();
138
+ EnumWindows(delegate(IntPtr h, IntPtr l) {
139
+ if (!IsWindowVisible(h) || IsIconic(h)) return true;
140
+ if (Cloaked(h) || !AltTabWorthy(h)) return true;
141
+ RECT r;
142
+ if (!Bounds(h, out r)) return true;
143
+ // Tool windows and tray hosts are real but never what anyone means.
144
+ if (r.Right - r.Left < 120 || r.Bottom - r.Top < 120) return true;
145
+ int len = GetWindowTextLength(h);
146
+ string title = "";
147
+ if (len > 0) {
148
+ var sb = new StringBuilder(len + 1);
149
+ GetWindowText(h, sb, sb.Capacity);
150
+ title = sb.ToString().Trim();
151
+ }
152
+ // An empty title is NOT a reason to drop the window. A custom title bar
153
+ // (Tauri or Electron with decorations off) leaves the OS title blank, as does
154
+ // an app whose web content has not set document.title yet — and dropping it
155
+ // makes a window the user is plainly looking at impossible to capture, by name
156
+ // OR as the foreground. Label it by its process so it stays nameable.
157
+ if (title.Length == 0) {
158
+ string pn = ProcName(h);
159
+ title = pn.Length > 0 ? pn : "(untitled window)";
160
+ }
161
+ // The leading marker is how the caller knows which window the user is
162
+ // actually looking at, so it can name it when asking permission.
163
+ uint wpid; GetWindowThreadProcessId(h, out wpid);
164
+ string hostCol = mark.Length == 0 && HostPids.Contains(wpid) ? "\thost" : "";
165
+ found.Add((h == fg && mark.Length == 0 ? "*" : "-") + mark + h.ToInt64().ToString() + "\t" + title + hostCol);
166
+ return true;
167
+ }, IntPtr.Zero);
168
+ return found;
169
+ }
170
+
171
+ public static string CaptureOn(string desk, IntPtr h, string path) {
172
+ return MwDesk.On(desk, () => Capture(h, path, string.IsNullOrEmpty(desk)));
173
+ }
174
+
175
+ // screen: whether a blank PrintWindow may fall back to copying the screen. Never for a
176
+ // window on the hidden desktop: the screen is the USER's, and that window is not on it.
177
+ public static string Capture(IntPtr h, string path, bool screen) {
178
+ RECT r;
179
+ if (!Bounds(h, out r)) return "ERR could not measure the window";
180
+ int w = r.Right - r.Left, ht = r.Bottom - r.Top;
181
+ if (w <= 0 || ht <= 0) return "ERR the window has no visible area";
182
+ using (var bmp = new Bitmap(w, ht)) {
183
+ bool drew = false;
184
+ using (var g = Graphics.FromImage(bmp)) {
185
+ IntPtr hdc = g.GetHdc();
186
+ drew = PrintWindow(h, hdc, 2); // PW_RENDERFULLCONTENT
187
+ g.ReleaseHdc(hdc);
188
+ }
189
+ if (!drew || Blank(bmp)) {
190
+ if (!screen) return "ERR the window drew nothing to capture";
191
+ using (var g = Graphics.FromImage(bmp)) {
192
+ g.CopyFromScreen(r.Left, r.Top, 0, 0, new Size(w, ht));
193
+ }
194
+ }
195
+ bmp.Save(path, ImageFormat.Png);
196
+ return "OK " + w + " " + ht;
197
+ }
198
+ }
199
+
200
+ // PrintWindow can report success and draw nothing. Sampling three corners of a
201
+ // fully transparent bitmap is enough to tell that apart from a real capture.
202
+ static bool Blank(Bitmap b) {
203
+ if (b.Width < 4 || b.Height < 4) return false;
204
+ return b.GetPixel(1, 1).A == 0
205
+ && b.GetPixel(b.Width / 2, b.Height / 2).A == 0
206
+ && b.GetPixel(b.Width - 2, b.Height - 2).A == 0;
207
+ }
208
+ }
209
+ ${DESK_CS}
210
+ "@
211
+
212
+ # Before any measurement, or every rectangle is in the wrong coordinate space.
213
+ [MwCapture]::Dpi() | Out-Null
214
+
215
+ if ($Mode -eq "host") {
216
+ Write-Output ([MwCapture]::HostWindow())
217
+ exit 0
218
+ }
219
+
220
+ if ($Mode -eq "list") {
221
+ # Which windows are the one this process runs in: walk up from it, stopping at the shell that
222
+ # started the whole session (the desktop, services), and take each console host that belongs to
223
+ # one of those on the way. Every process passed may own the window.
224
+ if ($Owner -gt 0) {
225
+ $procs = Get-CimInstance Win32_Process -Property ProcessId, ParentProcessId, Name
226
+ $parent = @{}
227
+ $name = @{}
228
+ foreach ($p in $procs) { $parent[[int]$p.ProcessId] = [int]$p.ParentProcessId; $name[[int]$p.ProcessId] = ([string]$p.Name).ToLower() }
229
+ $stop = @("explorer.exe", "services.exe", "wininit.exe", "winlogon.exe", "csrss.exe", "svchost.exe", "system")
230
+ $seen = @{}
231
+ $at = $Owner
232
+ while ($at -gt 0 -and -not $seen.ContainsKey($at)) {
233
+ $seen[$at] = $true
234
+ if ($stop -contains $name[$at]) { break }
235
+ [void][MwCapture]::HostPids.Add([uint32]$at)
236
+ $at = $parent[$at]
237
+ }
238
+ foreach ($p in $procs) {
239
+ $n = ([string]$p.Name).ToLower()
240
+ if (($n -eq "conhost.exe" -or $n -eq "openconsole.exe") -and [MwCapture]::HostPids.Contains([uint32]$p.ParentProcessId)) { [void][MwCapture]::HostPids.Add([uint32]$p.ProcessId) }
241
+ }
242
+ }
243
+ [MwCapture]::List("") | ForEach-Object { Write-Output $_ }
244
+ # The windows of apps started for testing, which are never on the screen.
245
+ if ($Hidden -and [MwDesk]::Exists($Hidden)) { Write-Output ([MwCapture]::ListOn($Hidden)) }
246
+ exit 0
247
+ }
248
+
249
+ if ($Mode -eq "capture") {
250
+ $h = if ($Handle -eq "foreground") { [MwCapture]::GetForegroundWindow() } else { [IntPtr][Int64]$Handle }
251
+ if ($h -eq [IntPtr]::Zero) { Write-Output "ERR no such window"; exit 1 }
252
+ $r = [MwCapture]::CaptureOn($Desktop, $h, $Out)
253
+ Write-Output $r
254
+ if ($r.StartsWith("ERR")) { exit 1 }
255
+ exit 0
256
+ }
257
+
258
+ Write-Output "ERR unknown mode"
259
+ exit 1
215
260
  `;
216
261
  let scriptPath = null;
217
262
  /** Write the capture script to a temp file once per process. */
@@ -225,10 +270,12 @@ async function ensureScript() {
225
270
  return path;
226
271
  }
227
272
  /** Run the script in one of its two modes. Rejects with the script's own message. */
228
- async function runScript(args, signal) {
273
+ async function runScript(args, signal, shareConsole = false) {
229
274
  const script = await ensureScript();
230
275
  return await new Promise((resolve, reject) => {
231
- const child = spawn("powershell.exe", ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-File", script, ...args], { windowsHide: true });
276
+ const child = spawn("powershell.exe", ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-File", script, ...args],
277
+ // Hidden, with a console of its own, unless it must see THIS process's console (see hostWindowHandle).
278
+ shareConsole ? { stdio: ["ignore", "pipe", "pipe"] } : { windowsHide: true });
232
279
  let out = "";
233
280
  let err = "";
234
281
  const timer = setTimeout(() => {
@@ -269,11 +316,14 @@ export function parseWindowList(stdout) {
269
316
  if (tab <= 0)
270
317
  continue;
271
318
  const marked = line.slice(0, tab).trim();
272
- const title = line.slice(tab + 1).trim();
319
+ // A third column, "host", marks the window this process runs in.
320
+ const rest = line.slice(tab + 1).split("\t");
321
+ const host = rest.length > 1 && rest[rest.length - 1].trim() === "host";
322
+ const title = (host ? rest.slice(0, -1) : rest).join("\t").trim();
273
323
  const match = new RegExp(`^([*-])(${HIDDEN_MARK}?\\d+)$`).exec(marked);
274
324
  if (!match || !title)
275
325
  continue;
276
- windows.push({ handle: match[2], title, foreground: match[1] === "*" });
326
+ windows.push({ handle: match[2], title, foreground: match[1] === "*", ...(host ? { host: true } : {}) });
277
327
  }
278
328
  return windows;
279
329
  }
@@ -283,7 +333,40 @@ export function parseWindowList(stdout) {
283
333
  * title (a custom title bar) kept and labelled by its process rather than dropped.
284
334
  */
285
335
  export async function listWindows(signal) {
286
- return parseWindowList(await runScript(["-Mode", "list", "-Hidden", hiddenDesktopName()], signal));
336
+ const [raw, host] = await Promise.all([
337
+ runScript(["-Mode", "list", "-Hidden", hiddenDesktopName(), "-Owner", String(process.pid)], signal),
338
+ hostWindowHandle(signal),
339
+ ]);
340
+ const windows = parseWindowList(raw);
341
+ // The terminal's own window: found from the console this process is attached to, which the list cannot see
342
+ // (Windows Terminal is not a parent of the shell, only the owner of its window).
343
+ if (host)
344
+ for (const w of windows)
345
+ if (w.handle === host)
346
+ w.host = true;
347
+ return windows;
348
+ }
349
+ let hostHandleCache;
350
+ /**
351
+ * The window of the terminal this process is typed into, as a handle, or null when it has none (the desktop
352
+ * app) or it cannot be told. Asked once and kept: it does not change while the process runs. The question
353
+ * is put by a child that shares this console rather than making one of its own, since a console is what
354
+ * names the window, and that is only done when this process has a terminal at all, so a program with none
355
+ * is never made to open a window.
356
+ */
357
+ export async function hostWindowHandle(signal) {
358
+ if (hostHandleCache !== undefined)
359
+ return hostHandleCache;
360
+ if (!process.stdout.isTTY && !process.stdin.isTTY)
361
+ return (hostHandleCache = null);
362
+ try {
363
+ const out = (await runScript(["-Mode", "host"], signal, true)).trim().split(/\s+/).pop() ?? "";
364
+ hostHandleCache = /^\d+$/.test(out) ? out : null;
365
+ }
366
+ catch {
367
+ hostHandleCache = null;
368
+ }
369
+ return hostHandleCache;
287
370
  }
288
371
  /** Capture one window to `outPath`. `handle` may be the literal "foreground". */
289
372
  export async function captureWindow(handle, outPath, signal) {
@@ -1 +1 @@
1
- {"version":3,"file":"screenshotWin.js","sourceRoot":"","sources":["../../src/tools/screenshotWin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAWzF,MAAM,aAAa,GAAG,MAAM,CAAC;AAE7B,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+DAuEsC,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2ExE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;CAwBR,CAAC;AAEF,IAAI,UAAU,GAAkB,IAAI,CAAC;AAErC,gEAAgE;AAChE,KAAK,UAAU,YAAY;IACzB,IAAI,UAAU;QAAE,OAAO,UAAU,CAAC;IAClC,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IACtC,MAAM,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,UAAU,GAAG,IAAI,CAAC;IAClB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,qFAAqF;AACrF,KAAK,UAAU,SAAS,CAAC,IAAc,EAAE,MAAoB;IAC3D,MAAM,MAAM,GAAG,MAAM,YAAY,EAAE,CAAC;IACpC,OAAO,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACnD,MAAM,KAAK,GAAG,KAAK,CACjB,gBAAgB,EAChB,CAAC,YAAY,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,EACzF,EAAE,WAAW,EAAE,IAAI,EAAE,CACtB,CAAC;QACF,IAAI,GAAG,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,GAAG,EAAE,CAAC;QACb,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,KAAK,CAAC,IAAI,EAAE,CAAC;YACb,MAAM,CAAC,IAAI,KAAK,CAAC,gCAAgC,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;QAC7E,CAAC,EAAE,aAAa,CAAC,CAAC;QAClB,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAE3D,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QAC9D,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QAC9D,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;YACtB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC9C,MAAM,CAAC,CAAC,CAAC,CAAC;QACZ,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC9C,IAAI,IAAI,KAAK,CAAC;gBAAE,OAAO,CAAC,GAAG,CAAC,CAAC;;gBACxB,MAAM,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,qBAAqB,IAAI,EAAE,CAAC,CAAC,CAAC;QAC1F,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,SAAS,CAAC,IAAY;IAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;AACxF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,MAAM,OAAO,GAAiB,EAAE,CAAC;IACjC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QACzC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,GAAG,IAAI,CAAC;YAAE,SAAS;QACvB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,WAAW,WAAW,SAAS,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvE,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK;YAAE,SAAS;QAC/B,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAE,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAoB;IACpD,OAAO,eAAe,CAAC,MAAM,SAAS,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AACrG,CAAC;AAED,iFAAiF;AACjF,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAc,EACd,OAAe,EACf,MAAoB;IAEpB,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IAClC,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;IACxH,MAAM,KAAK,GAAG,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7C,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,+BAA+B,CAAC,CAAC;IAC/E,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC/D,CAAC"}
1
+ {"version":3,"file":"screenshotWin.js","sourceRoot":"","sources":["../../src/tools/screenshotWin.ts"],"names":[],"mappings":"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"}