codeloop-mcp-server 0.1.64 → 0.1.66
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/dist/auth/critical_floors.d.ts.map +1 -1
- package/dist/auth/critical_floors.js +8 -0
- package/dist/auth/critical_floors.js.map +1 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/runners/base.d.ts.map +1 -1
- package/dist/runners/base.js +86 -14
- package/dist/runners/base.js.map +1 -1
- package/dist/runners/flutter.d.ts.map +1 -1
- package/dist/runners/flutter.js +73 -3
- package/dist/runners/flutter.js.map +1 -1
- package/dist/runners/modal_detector.d.ts +27 -7
- package/dist/runners/modal_detector.d.ts.map +1 -1
- package/dist/runners/modal_detector.js +124 -31
- package/dist/runners/modal_detector.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/runners/base.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACb,YAAY,CAad;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQ1E;AA2CD,wBAAsB,UAAU,CAC9B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAOjC,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/runners/base.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACb,YAAY,CAad;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQ1E;AA2CD,wBAAsB,UAAU,CAC9B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAOjC,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CAyOrF"}
|
package/dist/runners/base.js
CHANGED
|
@@ -151,6 +151,17 @@ timeoutMs) {
|
|
|
151
151
|
// give us. Node v16+ resolves `.cmd` / `.bat` extensions itself
|
|
152
152
|
// via uv_spawn, so this is safe for `npm` / `npx` / `vitest`.
|
|
153
153
|
const anyMultilineArg = resolvedArgs.some((a) => /[\r\n]/.test(a));
|
|
154
|
+
// When a timeout is requested we must be able to kill the ENTIRE process
|
|
155
|
+
// tree, not just the direct child. With `shell: true` (the default path
|
|
156
|
+
// below) the direct child is `/bin/sh -c "<cmd>"`; SIGKILLing the shell
|
|
157
|
+
// does NOT reap a grandchild that the shell forked (e.g. `flutter` is a
|
|
158
|
+
// bash script that spawns `dart`; `node -e …` under dash). The grandchild
|
|
159
|
+
// keeps the stdout/stderr pipe fds open, so the `close` event never fires
|
|
160
|
+
// and the promise hangs forever — defeating the timeout entirely. Making
|
|
161
|
+
// the child a process-group leader (`detached`) lets us SIGKILL the whole
|
|
162
|
+
// group via `process.kill(-pid)` on POSIX. Only enabled when a timeout is
|
|
163
|
+
// set, so the default (untimed) behaviour is byte-for-byte unchanged.
|
|
164
|
+
const useProcessGroup = !!(timeoutMs && timeoutMs > 0) && !isWindows;
|
|
154
165
|
let child;
|
|
155
166
|
if (isWindows && anyMultilineArg) {
|
|
156
167
|
child = spawn(resolvedCmd, resolvedArgs, {
|
|
@@ -158,6 +169,7 @@ timeoutMs) {
|
|
|
158
169
|
shell: false,
|
|
159
170
|
stdio: ["pipe", "pipe", "pipe"],
|
|
160
171
|
env: { ...process.env, ...(extraEnv ?? {}) },
|
|
172
|
+
detached: useProcessGroup,
|
|
161
173
|
});
|
|
162
174
|
}
|
|
163
175
|
else {
|
|
@@ -176,6 +188,7 @@ timeoutMs) {
|
|
|
176
188
|
shell: true,
|
|
177
189
|
stdio: ["pipe", "pipe", "pipe"],
|
|
178
190
|
env: { ...process.env, ...(extraEnv ?? {}) },
|
|
191
|
+
detached: useProcessGroup,
|
|
179
192
|
});
|
|
180
193
|
}
|
|
181
194
|
const stdoutChunks = [];
|
|
@@ -183,20 +196,61 @@ timeoutMs) {
|
|
|
183
196
|
child.stdout.on("data", (chunk) => stdoutChunks.push(chunk));
|
|
184
197
|
child.stderr.on("data", (chunk) => stderrChunks.push(chunk));
|
|
185
198
|
let timedOut = false;
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
199
|
+
let settled = false;
|
|
200
|
+
let timer = null;
|
|
201
|
+
let forceResolveTimer = null;
|
|
202
|
+
// Kill the whole process tree, not just the direct child. On POSIX the
|
|
203
|
+
// child is a group leader (detached, see useProcessGroup) so a negative
|
|
204
|
+
// pid signals the entire group — reaping the shell AND any grandchild it
|
|
205
|
+
// forked. On Windows we shell out to `taskkill /T /F` to walk the tree.
|
|
206
|
+
const killTree = () => {
|
|
207
|
+
const pid = child.pid;
|
|
208
|
+
if (!pid) {
|
|
189
209
|
try {
|
|
190
210
|
child.kill("SIGKILL");
|
|
191
211
|
}
|
|
212
|
+
catch { /* already gone */ }
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
if (isWindows) {
|
|
216
|
+
try {
|
|
217
|
+
spawn("taskkill", ["/pid", String(pid), "/T", "/F"], {
|
|
218
|
+
stdio: "ignore",
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
try {
|
|
223
|
+
child.kill("SIGKILL");
|
|
224
|
+
}
|
|
225
|
+
catch { /* already gone */ }
|
|
226
|
+
}
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
if (useProcessGroup) {
|
|
230
|
+
try {
|
|
231
|
+
process.kill(-pid, "SIGKILL"); // negative pid = process group
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
192
234
|
catch {
|
|
193
|
-
/*
|
|
235
|
+
/* fall through to single-process kill */
|
|
194
236
|
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
|
|
237
|
+
}
|
|
238
|
+
try {
|
|
239
|
+
child.kill("SIGKILL");
|
|
240
|
+
}
|
|
241
|
+
catch { /* already gone */ }
|
|
242
|
+
};
|
|
243
|
+
// A SIGKILLed tree normally fires `close` promptly, but if any lingering
|
|
244
|
+
// fd keeps the pipe open we must still resolve. This fallback guarantees
|
|
245
|
+
// the promise settles within 1.5s of a timeout kill regardless.
|
|
246
|
+
const finish = (code) => {
|
|
247
|
+
if (settled)
|
|
248
|
+
return;
|
|
249
|
+
settled = true;
|
|
198
250
|
if (timer)
|
|
199
251
|
clearTimeout(timer);
|
|
252
|
+
if (forceResolveTimer)
|
|
253
|
+
clearTimeout(forceResolveTimer);
|
|
200
254
|
const duration_ms = Date.now() - start;
|
|
201
255
|
const stdout = Buffer.concat(stdoutChunks).toString("utf-8");
|
|
202
256
|
const stderr = Buffer.concat(stderrChunks).toString("utf-8");
|
|
@@ -207,12 +261,15 @@ timeoutMs) {
|
|
|
207
261
|
catch { /* best-effort */ }
|
|
208
262
|
}
|
|
209
263
|
if (logPath) {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
264
|
+
try {
|
|
265
|
+
mkdirSync(dirname(logPath), { recursive: true });
|
|
266
|
+
writeFileSync(logPath, `$ ${cmd} ${args.join(" ")}\n` +
|
|
267
|
+
`exit_code: ${timedOut ? 124 : code ?? 1}\n` +
|
|
268
|
+
`duration_ms: ${duration_ms}\n\n` +
|
|
269
|
+
`--- stdout ---\n${stdout}\n` +
|
|
270
|
+
`--- stderr ---\n${stderr}\n`);
|
|
271
|
+
}
|
|
272
|
+
catch { /* best-effort */ }
|
|
216
273
|
}
|
|
217
274
|
resolve({
|
|
218
275
|
exit_code: timedOut ? 124 : (code ?? 1),
|
|
@@ -222,10 +279,25 @@ timeoutMs) {
|
|
|
222
279
|
: stderr,
|
|
223
280
|
duration_ms,
|
|
224
281
|
});
|
|
225
|
-
}
|
|
282
|
+
};
|
|
283
|
+
timer =
|
|
284
|
+
timeoutMs && timeoutMs > 0
|
|
285
|
+
? setTimeout(() => {
|
|
286
|
+
timedOut = true;
|
|
287
|
+
killTree();
|
|
288
|
+
// Safety net: settle even if `close` is somehow withheld.
|
|
289
|
+
forceResolveTimer = setTimeout(() => finish(null), 1500);
|
|
290
|
+
}, timeoutMs)
|
|
291
|
+
: null;
|
|
292
|
+
child.on("close", (code) => finish(code));
|
|
226
293
|
child.on("error", (err) => {
|
|
294
|
+
if (settled)
|
|
295
|
+
return;
|
|
296
|
+
settled = true;
|
|
227
297
|
if (timer)
|
|
228
298
|
clearTimeout(timer);
|
|
299
|
+
if (forceResolveTimer)
|
|
300
|
+
clearTimeout(forceResolveTimer);
|
|
229
301
|
if (scriptCleanup) {
|
|
230
302
|
try {
|
|
231
303
|
unlinkSync(scriptCleanup);
|
package/dist/runners/base.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/runners/base.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/runners/base.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flutter.d.ts","sourceRoot":"","sources":["../../src/runners/flutter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"flutter.d.ts","sourceRoot":"","sources":["../../src/runners/flutter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAkC9C,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,YAAY,CAAC,CAgDvB;AAED,wBAAsB,cAAc,CAClC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,YAAY,CAAC,CAkDvB;AAED,wBAAsB,yBAAyB,CAC7C,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,YAAY,CAAC,CA4DvB"}
|
package/dist/runners/flutter.js
CHANGED
|
@@ -1,6 +1,31 @@
|
|
|
1
1
|
import { runCommand, checkToolAvailable, makeSkippedResult } from "./base.js";
|
|
2
2
|
import { existsSync } from "fs";
|
|
3
3
|
import { join } from "path";
|
|
4
|
+
// Wall-clock watchdogs for the Flutter verify commands. Before this, all
|
|
5
|
+
// three primary Flutter runners called runCommand WITHOUT a timeout, so any
|
|
6
|
+
// one of them could hang `codeloop_verify` forever — most commonly the
|
|
7
|
+
// integration-test step waiting on a device/emulator that never boots (no
|
|
8
|
+
// `-d` flag, no device probe), or `flutter analyze` stalling on an implicit
|
|
9
|
+
// `pub get` over a slow/blocked network. On SIGKILL runCommand returns
|
|
10
|
+
// exit_code 124, which we surface as an explicit failure with guidance
|
|
11
|
+
// instead of an indefinite freeze. Caps mirror static_analysis.ts (4 min)
|
|
12
|
+
// and coverage.ts (5 min); integration tests get a little more headroom.
|
|
13
|
+
const ANALYZE_TIMEOUT_MS = 240_000; // 4 min
|
|
14
|
+
const TEST_TIMEOUT_MS = 300_000; // 5 min
|
|
15
|
+
const INTEGRATION_TIMEOUT_MS = 360_000; // 6 min
|
|
16
|
+
// Force non-interactive Flutter: `CI=true` suppresses the first-run analytics
|
|
17
|
+
// consent prompt and disables animations, so a brand-new machine never blocks
|
|
18
|
+
// waiting on a tool message.
|
|
19
|
+
const NONINTERACTIVE_ENV = { CI: "true" };
|
|
20
|
+
function timeoutNote(cmd, timeoutMs) {
|
|
21
|
+
const mins = Math.round(timeoutMs / 60_000);
|
|
22
|
+
return (`[CodeLoop] \`${cmd}\` was killed after ${mins} min (timeout). ` +
|
|
23
|
+
`This usually means it was waiting on something interactive — a cold ` +
|
|
24
|
+
`emulator/simulator or connected device (integration tests need one, and ` +
|
|
25
|
+
`CodeLoop does not boot one for you), or an implicit \`flutter pub get\` ` +
|
|
26
|
+
`stalling on the network. Boot a device/emulator (or run on \`-d chrome\`/ ` +
|
|
27
|
+
`desktop) and run \`flutter pub get\` manually, then re-verify.`);
|
|
28
|
+
}
|
|
4
29
|
export async function runFlutterAnalyze(cwd, logPath) {
|
|
5
30
|
if (!existsSync(join(cwd, "pubspec.yaml"))) {
|
|
6
31
|
return makeSkippedResult("flutter_analyze", "No pubspec.yaml found");
|
|
@@ -8,7 +33,22 @@ export async function runFlutterAnalyze(cwd, logPath) {
|
|
|
8
33
|
if (!(await checkToolAvailable("flutter"))) {
|
|
9
34
|
return makeSkippedResult("flutter_analyze", "flutter not found on PATH");
|
|
10
35
|
}
|
|
11
|
-
const result = await runCommand("flutter", ["analyze", "--no-fatal-infos"], cwd, logPath);
|
|
36
|
+
const result = await runCommand("flutter", ["analyze", "--no-fatal-infos"], cwd, logPath, NONINTERACTIVE_ENV, ANALYZE_TIMEOUT_MS);
|
|
37
|
+
if (result.exit_code === 124) {
|
|
38
|
+
const note = timeoutNote("flutter analyze --no-fatal-infos", ANALYZE_TIMEOUT_MS);
|
|
39
|
+
return {
|
|
40
|
+
runner_name: "flutter_analyze",
|
|
41
|
+
available: true,
|
|
42
|
+
exit_code: 124,
|
|
43
|
+
passed: 0,
|
|
44
|
+
failed: 1,
|
|
45
|
+
skipped: 0,
|
|
46
|
+
log_path: logPath,
|
|
47
|
+
duration_ms: result.duration_ms,
|
|
48
|
+
stdout: result.stdout,
|
|
49
|
+
stderr: `${note}\n${result.stderr}`,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
12
52
|
const analyzeResult = parseAnalyzeOutput(result.stdout + result.stderr);
|
|
13
53
|
return {
|
|
14
54
|
runner_name: "flutter_analyze",
|
|
@@ -30,7 +70,22 @@ export async function runFlutterTest(cwd, logPath) {
|
|
|
30
70
|
if (!(await checkToolAvailable("flutter"))) {
|
|
31
71
|
return makeSkippedResult("flutter_test", "flutter not found on PATH");
|
|
32
72
|
}
|
|
33
|
-
const result = await runCommand("flutter", ["test", "--reporter=compact"], cwd, logPath);
|
|
73
|
+
const result = await runCommand("flutter", ["test", "--reporter=compact"], cwd, logPath, NONINTERACTIVE_ENV, TEST_TIMEOUT_MS);
|
|
74
|
+
if (result.exit_code === 124) {
|
|
75
|
+
const note = timeoutNote("flutter test", TEST_TIMEOUT_MS);
|
|
76
|
+
return {
|
|
77
|
+
runner_name: "flutter_test",
|
|
78
|
+
available: true,
|
|
79
|
+
exit_code: 124,
|
|
80
|
+
passed: 0,
|
|
81
|
+
failed: 1,
|
|
82
|
+
skipped: 0,
|
|
83
|
+
log_path: logPath,
|
|
84
|
+
duration_ms: result.duration_ms,
|
|
85
|
+
stdout: result.stdout,
|
|
86
|
+
stderr: `${note}\n${result.stderr}`,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
34
89
|
const { passed, failed, skipped } = parseFlutterTestOutput(result.stdout + result.stderr);
|
|
35
90
|
return {
|
|
36
91
|
runner_name: "flutter_test",
|
|
@@ -59,7 +114,22 @@ export async function runFlutterIntegrationTest(cwd, logPath) {
|
|
|
59
114
|
}
|
|
60
115
|
const testPath = hasIntegration ? "integration_test/" : "test/";
|
|
61
116
|
const args = ["test", testPath, "--reporter=compact"];
|
|
62
|
-
const result = await runCommand("flutter", args, cwd, logPath);
|
|
117
|
+
const result = await runCommand("flutter", args, cwd, logPath, NONINTERACTIVE_ENV, INTEGRATION_TIMEOUT_MS);
|
|
118
|
+
if (result.exit_code === 124) {
|
|
119
|
+
const note = timeoutNote(`flutter test ${testPath}`, INTEGRATION_TIMEOUT_MS);
|
|
120
|
+
return {
|
|
121
|
+
runner_name: "flutter_integration_test",
|
|
122
|
+
available: true,
|
|
123
|
+
exit_code: 124,
|
|
124
|
+
passed: 0,
|
|
125
|
+
failed: 1,
|
|
126
|
+
skipped: 0,
|
|
127
|
+
log_path: logPath,
|
|
128
|
+
duration_ms: result.duration_ms,
|
|
129
|
+
stdout: result.stdout,
|
|
130
|
+
stderr: `${note}\n${result.stderr}`,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
63
133
|
const { passed, failed, skipped } = parseFlutterTestOutput(result.stdout + result.stderr);
|
|
64
134
|
return {
|
|
65
135
|
runner_name: "flutter_integration_test",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flutter.js","sourceRoot":"","sources":["../../src/runners/flutter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAE9E,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,GAAW,EACX,OAAe;IAEf,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC;QAC3C,OAAO,iBAAiB,CAAC,iBAAiB,EAAE,uBAAuB,CAAC,CAAC;IACvE,CAAC;IAED,IAAI,CAAC,CAAC,MAAM,kBAAkB,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;QAC3C,OAAO,iBAAiB,CAAC,iBAAiB,EAAE,2BAA2B,CAAC,CAAC;IAC3E,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,SAAS,EAAE,CAAC,SAAS,EAAE,kBAAkB,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"flutter.js","sourceRoot":"","sources":["../../src/runners/flutter.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,10 +12,12 @@ import type { CodeLoopConfig } from "@codelooptech/shared";
|
|
|
12
12
|
* - Browser: query Playwright's page for alert/confirm dialogs
|
|
13
13
|
* and visible overlay elements (role=dialog, aria-modal=true,
|
|
14
14
|
* CSS classes that match common modal libraries).
|
|
15
|
-
* - Windows desktop: PowerShell +
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
15
|
+
* - Windows desktop: PowerShell + Win32 `EnumWindows` (0.1.65 H13;
|
|
16
|
+
* replaced the UIA control-view walk that could not see owned
|
|
17
|
+
* `MessageBox` dialogs). Reads each top-level window's owner
|
|
18
|
+
* (GW_OWNER), enabled state, pid, class and title, plus the
|
|
19
|
+
* foreground window, and flags an app-owned dialog via the
|
|
20
|
+
* owner-chain / owner-disabled / foreground signals.
|
|
19
21
|
* - macOS desktop: AppleScript — `every window of process whose
|
|
20
22
|
* subrole is "AXDialog" or "AXSystemDialog"`.
|
|
21
23
|
* - Linux desktop: xdotool / xprop walk for windows whose WM_NAME
|
|
@@ -71,7 +73,7 @@ export declare function detectModal(opts: {
|
|
|
71
73
|
cwd: string;
|
|
72
74
|
config?: CodeLoopConfig;
|
|
73
75
|
}): Promise<ModalDetectionResult>;
|
|
74
|
-
/** 0.1.63 H12 — one top-level window row from the
|
|
76
|
+
/** 0.1.63 H12 / 0.1.65 H13 — one top-level window row from the probe. */
|
|
75
77
|
export interface RawModalWindow {
|
|
76
78
|
name?: string;
|
|
77
79
|
class_name?: string;
|
|
@@ -79,13 +81,31 @@ export interface RawModalWindow {
|
|
|
79
81
|
is_modal?: boolean;
|
|
80
82
|
/** Win32 ProcessId of the owning process (0.1.63 H12). */
|
|
81
83
|
process_id?: number;
|
|
84
|
+
/**
|
|
85
|
+
* 0.1.65 H13 — Win32 GW_OWNER handle. A `MessageBox(hwndOwner, …)` /
|
|
86
|
+
* modal dialog is an OWNED top-level window whose owner is the app's
|
|
87
|
+
* main window. This is the single most reliable, title-independent
|
|
88
|
+
* signal that a dialog belongs to the app — and the one UIA's
|
|
89
|
+
* control-view enumeration never exposed (the recurring miss).
|
|
90
|
+
*/
|
|
91
|
+
owner_hwnd?: number | string;
|
|
92
|
+
/** 0.1.65 H13 — IsWindowVisible. */
|
|
93
|
+
is_visible?: boolean;
|
|
94
|
+
/** 0.1.65 H13 — IsWindowEnabled. A visible-but-DISABLED main window
|
|
95
|
+
* means a modal is blocking it (Windows disables a modal's owner). */
|
|
96
|
+
is_enabled?: boolean;
|
|
82
97
|
}
|
|
83
|
-
/** 0.1.63 H12 — full
|
|
84
|
-
* resolved app process identity (pid(s) + main-window handle(s))
|
|
98
|
+
/** 0.1.63 H12 / 0.1.65 H13 — full probe payload: every top-level window
|
|
99
|
+
* plus the resolved app process identity (pid(s) + main-window handle(s))
|
|
100
|
+
* and the current foreground window. */
|
|
85
101
|
export interface RawModalProbe {
|
|
86
102
|
windows: RawModalWindow[];
|
|
87
103
|
app_pids: number[];
|
|
88
104
|
app_main_hwnds: Array<number | string>;
|
|
105
|
+
/** 0.1.65 H13 — GetForegroundWindow() HWND. After a click that raises a
|
|
106
|
+
* dialog, the dialog IS the foreground window — a robust anchor even
|
|
107
|
+
* when app-title resolution fails. */
|
|
108
|
+
foreground_hwnd?: number | string;
|
|
89
109
|
}
|
|
90
110
|
/**
|
|
91
111
|
* 0.1.63 H12 — pure modal selection (no I/O), unit-testable.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modal_detector.d.ts","sourceRoot":"","sources":["../../src/runners/modal_detector.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D
|
|
1
|
+
{"version":3,"file":"modal_detector.d.ts","sourceRoot":"","sources":["../../src/runners/modal_detector.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH;;;;;;;GAOG;AACH,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEvE,MAAM,WAAW,oBAAoB;IACnC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,sEAAsE;IACtE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,uFAAuF;IACvF,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gFAAgF;IAChF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oFAAoF;IACpF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+FAA+F;IAC/F,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,4CAA4C;IAC5C,WAAW,EAAE,SAAS,GAAG,SAAS,GAAG,kBAAkB,GAAG,eAAe,GAAG,SAAS,CAAC;CACvF;AAqDD,4EAA4E;AAC5E,eAAO,MAAM,oBAAoB,QACkF,CAAC;AACpH,eAAO,MAAM,kBAAkB,QACuD,CAAC;AAKvF,kFAAkF;AAClF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAgB7E;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACtC,WAAW,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,kBAAkB,GAAG,eAAe,CAAC;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAiBhC;AA4BD,yEAAyE;AACzE,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,oCAAoC;IACpC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;0EACsE;IACtE,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;wCAEwC;AACxC,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,cAAc,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IACvC;;0CAEsC;IACtC,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACnC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,oBAAoB,CA0K/F;AAgKD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAiB5D"}
|
|
@@ -138,6 +138,7 @@ export function selectWindowsModal(probe, appName) {
|
|
|
138
138
|
const appNorm = appLower.replace(/\s+/g, "");
|
|
139
139
|
const appPids = new Set((probe.app_pids ?? []).map((p) => Number(p)));
|
|
140
140
|
const mainHwnds = new Set((probe.app_main_hwnds ?? []).map((h) => String(h)));
|
|
141
|
+
const fgHwnd = probe.foreground_hwnd != null ? String(probe.foreground_hwnd) : null;
|
|
141
142
|
const wins = probe.windows ?? [];
|
|
142
143
|
const nm = (w) => w.name ?? "";
|
|
143
144
|
const cls = (w) => (w.class_name ?? "").trim();
|
|
@@ -149,10 +150,21 @@ export function selectWindowsModal(probe, appName) {
|
|
|
149
150
|
};
|
|
150
151
|
const isOwned = (w) => w.process_id != null && appPids.has(Number(w.process_id));
|
|
151
152
|
const isMainWindow = (w) => w.hwnd != null && mainHwnds.has(String(w.hwnd));
|
|
153
|
+
// 0.1.65 H13 — owner-chain: the window's GW_OWNER is one of the app's
|
|
154
|
+
// main windows. This is THE reliable MessageBox signal.
|
|
155
|
+
const isOwnedByApp = (w) => w.owner_hwnd != null && mainHwnds.has(String(w.owner_hwnd));
|
|
156
|
+
// Visibility defaults to true when the probe didn't report it (older
|
|
157
|
+
// probes / unit fixtures) so we never regress on missing data.
|
|
158
|
+
const isVisible = (w) => w.is_visible !== false;
|
|
159
|
+
const isForeground = (w) => fgHwnd != null && w.hwnd != null && String(w.hwnd) === fgHwnd;
|
|
152
160
|
const hasDialogClass = (w) => GENERIC_DIALOG_CLASS_NAMES.has(cls(w)) || FILE_DIALOG_CLASS_NAMES.includes(cls(w));
|
|
153
161
|
const hasModalNamePattern = (w) => FILE_DIALOG_NAME_PATTERNS.some((re) => re.test(nm(w))) ||
|
|
154
162
|
CONFIRM_NAME_PATTERN.test(nm(w)) ||
|
|
155
163
|
ALERT_NAME_PATTERN.test(nm(w));
|
|
164
|
+
// 0.1.65 H13 — is the app's own main window visible-but-DISABLED? Windows
|
|
165
|
+
// disables a modal dialog's owner, so a disabled owner is near-proof a
|
|
166
|
+
// modal is blocking the app, even if we can't pin which window it is.
|
|
167
|
+
const appMainDisabled = wins.some((w) => isMainWindow(w) && isVisible(w) && w.is_enabled === false);
|
|
156
168
|
const build = (w, confidence, descPrefix) => {
|
|
157
169
|
const name = nm(w) || "(unnamed)";
|
|
158
170
|
const kind = classifyModalKind(name, cls(w) || undefined);
|
|
@@ -169,24 +181,70 @@ export function selectWindowsModal(probe, appName) {
|
|
|
169
181
|
};
|
|
170
182
|
// Pass 1 — UIA explicitly flagged the window modal AND it's owned by /
|
|
171
183
|
// titled for our app (and is not the main window itself).
|
|
172
|
-
const explicit = wins.find((w) => w.is_modal && !isMainWindow(w) && (isOwned(w) || matchesAppFilter(nm(w))));
|
|
184
|
+
const explicit = wins.find((w) => w.is_modal && !isMainWindow(w) && (isOwned(w) || isOwnedByApp(w) || matchesAppFilter(nm(w))));
|
|
173
185
|
if (explicit)
|
|
174
|
-
return build(explicit, 0.
|
|
175
|
-
// Pass
|
|
176
|
-
//
|
|
177
|
-
//
|
|
186
|
+
return build(explicit, 0.92, "Windows modal");
|
|
187
|
+
// Pass A — 0.1.65 H13: OWNER-CHAIN. A visible, non-main window whose
|
|
188
|
+
// GW_OWNER is the app's main window is an owned dialog (the Win32 /
|
|
189
|
+
// WPF MessageBox the recurring bug kept missing). Title-, class-, and
|
|
190
|
+
// IsModal-INDEPENDENT — this is the strongest signal we have.
|
|
191
|
+
const ownerChain = wins.find((w) => isOwnedByApp(w) && !isMainWindow(w) && isVisible(w));
|
|
192
|
+
if (ownerChain) {
|
|
193
|
+
const kind = classifyModalKind(nm(ownerChain) || "(unnamed)", cls(ownerChain) || undefined);
|
|
194
|
+
return build(ownerChain, kind === "file_dialog" ? 0.85 : 0.92, "Windows owned dialog");
|
|
195
|
+
}
|
|
196
|
+
// Pass 2 — 0.1.63 H12: app-owned (same-PROCESS) SECONDARY top-level
|
|
197
|
+
// window. We require a dialog signal (modal flag, dialog class, or
|
|
198
|
+
// modal-ish title) so a legitimate second document window of a
|
|
178
199
|
// multi-window app is NOT mistaken for a modal.
|
|
179
200
|
const owned = wins.find((w) => isOwned(w) &&
|
|
180
201
|
!isMainWindow(w) &&
|
|
202
|
+
isVisible(w) &&
|
|
181
203
|
(w.is_modal || hasDialogClass(w) || hasModalNamePattern(w)));
|
|
182
204
|
if (owned) {
|
|
183
205
|
const kind = classifyModalKind(nm(owned) || "(unnamed)", cls(owned) || undefined);
|
|
184
206
|
return build(owned, kind === "file_dialog" ? 0.8 : 0.85, "Windows dialog");
|
|
185
207
|
}
|
|
208
|
+
// Pass B — 0.1.65 H13: the FOREGROUND window is a secondary window that
|
|
209
|
+
// belongs to the app (owner-chain or same process). After a click that
|
|
210
|
+
// pops a dialog, the dialog becomes foreground.
|
|
211
|
+
const fgOwned = wins.find((w) => isForeground(w) && !isMainWindow(w) && isVisible(w) && (isOwnedByApp(w) || isOwned(w)));
|
|
212
|
+
if (fgOwned) {
|
|
213
|
+
const kind = classifyModalKind(nm(fgOwned) || "(unnamed)", cls(fgOwned) || undefined);
|
|
214
|
+
return build(fgOwned, kind === "file_dialog" ? 0.82 : 0.85, "Windows foreground dialog");
|
|
215
|
+
}
|
|
216
|
+
// Pass C — 0.1.65 H13: the app's main window is visible-but-DISABLED.
|
|
217
|
+
// Some app-owned secondary window is blocking it; pick the best
|
|
218
|
+
// candidate (foreground → owner-chain → same-process), else report the
|
|
219
|
+
// block generically so the agent still handles it.
|
|
220
|
+
if (appMainDisabled) {
|
|
221
|
+
const blocker = wins.find((w) => isForeground(w) && !isMainWindow(w) && isVisible(w)) ??
|
|
222
|
+
wins.find((w) => isOwnedByApp(w) && !isMainWindow(w) && isVisible(w)) ??
|
|
223
|
+
wins.find((w) => isOwned(w) && !isMainWindow(w) && isVisible(w));
|
|
224
|
+
if (blocker) {
|
|
225
|
+
const kind = classifyModalKind(nm(blocker) || "(unnamed)", cls(blocker) || undefined);
|
|
226
|
+
return build(blocker, kind === "file_dialog" ? 0.8 : 0.85, "Windows modal (owner disabled)");
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
// Pass D — 0.1.65 H13: the FOREGROUND window is itself a dialog (generic
|
|
230
|
+
// Win32 dialog class OR a confirm/alert/file title) even when we could
|
|
231
|
+
// not resolve the app's process (the Photometry-DB title-mismatch case).
|
|
232
|
+
// Ownership-independent but low-false-positive: a foreground #32770 /
|
|
233
|
+
// confirm-titled window is overwhelmingly an active modal.
|
|
234
|
+
const fgDialog = wins.find((w) => isForeground(w) &&
|
|
235
|
+
!isMainWindow(w) &&
|
|
236
|
+
isVisible(w) &&
|
|
237
|
+
(hasDialogClass(w) || hasModalNamePattern(w)));
|
|
238
|
+
if (fgDialog) {
|
|
239
|
+
const kind = classifyModalKind(nm(fgDialog) || "(unnamed)", cls(fgDialog) || undefined);
|
|
240
|
+
return build(fgDialog, kind === "file_dialog" ? 0.78 : 0.82, "Windows foreground dialog");
|
|
241
|
+
}
|
|
186
242
|
// Pass 3 — file-dialog heuristic (unowned / app process unresolved).
|
|
187
243
|
// (a) a strong file NAME pattern fires app-filter-free; (b) a file CLASS
|
|
188
244
|
// match still needs the app filter so we don't grab unrelated OS chrome.
|
|
189
245
|
const fileDialog = wins.find((w) => {
|
|
246
|
+
if (!isVisible(w))
|
|
247
|
+
return false;
|
|
190
248
|
const byName = FILE_DIALOG_NAME_PATTERNS.some((re) => re.test(nm(w)));
|
|
191
249
|
if (byName)
|
|
192
250
|
return true;
|
|
@@ -208,7 +266,8 @@ export function selectWindowsModal(probe, appName) {
|
|
|
208
266
|
// Pass 4 — safety net: a generic Win32 dialog (#32770 / DirectUIHWND)
|
|
209
267
|
// titled like a confirm / alert is unambiguously a dialog even when we
|
|
210
268
|
// could not resolve the owning process (e.g. app lookup failed).
|
|
211
|
-
const confirmByName = wins.find((w) =>
|
|
269
|
+
const confirmByName = wins.find((w) => isVisible(w) &&
|
|
270
|
+
GENERIC_DIALOG_CLASS_NAMES.has(cls(w)) &&
|
|
212
271
|
(CONFIRM_NAME_PATTERN.test(nm(w)) || ALERT_NAME_PATTERN.test(nm(w))));
|
|
213
272
|
if (confirmByName)
|
|
214
273
|
return build(confirmByName, 0.7, "Windows dialog");
|
|
@@ -217,31 +276,63 @@ export function selectWindowsModal(probe, appName) {
|
|
|
217
276
|
async function detectWindowsModal(opts) {
|
|
218
277
|
const app = opts.app_name ?? "";
|
|
219
278
|
const psLiteral = app.replace(/'/g, "''");
|
|
220
|
-
//
|
|
221
|
-
//
|
|
222
|
-
//
|
|
223
|
-
//
|
|
224
|
-
//
|
|
225
|
-
//
|
|
226
|
-
//
|
|
279
|
+
// 0.1.65 H13 — Win32 `EnumWindows` probe (replaces the UIA control-view
|
|
280
|
+
// walk). The recurring out-of-app confirm regressed because a Win32 /
|
|
281
|
+
// WPF `MessageBox(hwndOwner, …)` is an OWNED top-level window that UIA's
|
|
282
|
+
// control view does NOT expose as a direct child of the root element —
|
|
283
|
+
// so `RootElement.FindAll(Children, ControlType::Window)` returned ONLY
|
|
284
|
+
// the main window ("only the main window exists") and every downstream
|
|
285
|
+
// pass was starved of the dialog row. `EnumWindows` enumerates EVERY
|
|
286
|
+
// top-level window and, crucially, lets us read each window's owner
|
|
287
|
+
// (GW_OWNER), enabled state, pid, class and title — plus the foreground
|
|
288
|
+
// window — which are the title- and IsModal-independent signals the
|
|
289
|
+
// selector now keys off (owner-chain / owner-disabled / foreground).
|
|
290
|
+
//
|
|
291
|
+
// Fields per window are tab-joined inside C# (delimiter stripped from
|
|
292
|
+
// class/title) to dodge anonymous-type JSON quirks; PowerShell parses
|
|
293
|
+
// them back into the {hwnd,pid,owner_hwnd,is_enabled,class_name,name}
|
|
294
|
+
// shape selectWindowsModal expects.
|
|
227
295
|
const script = [
|
|
228
|
-
|
|
229
|
-
"
|
|
230
|
-
"
|
|
231
|
-
"
|
|
296
|
+
'Add-Type @"',
|
|
297
|
+
"using System;",
|
|
298
|
+
"using System.Text;",
|
|
299
|
+
"using System.Collections.Generic;",
|
|
300
|
+
"using System.Runtime.InteropServices;",
|
|
301
|
+
"public class ClModalEnum {",
|
|
302
|
+
" public delegate bool EnumProc(IntPtr h, IntPtr l);",
|
|
303
|
+
' [DllImport("user32.dll")] public static extern bool EnumWindows(EnumProc cb, IntPtr l);',
|
|
304
|
+
' [DllImport("user32.dll")] public static extern bool IsWindowVisible(IntPtr h);',
|
|
305
|
+
' [DllImport("user32.dll")] public static extern bool IsWindowEnabled(IntPtr h);',
|
|
306
|
+
' [DllImport("user32.dll", CharSet=CharSet.Auto)] public static extern int GetWindowText(IntPtr h, StringBuilder s, int n);',
|
|
307
|
+
' [DllImport("user32.dll", CharSet=CharSet.Auto)] public static extern int GetClassName(IntPtr h, StringBuilder s, int n);',
|
|
308
|
+
' [DllImport("user32.dll")] public static extern uint GetWindowThreadProcessId(IntPtr h, out uint pid);',
|
|
309
|
+
' [DllImport("user32.dll")] public static extern IntPtr GetWindow(IntPtr h, uint cmd);',
|
|
310
|
+
' [DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow();',
|
|
311
|
+
" public static List<string> Rows() {",
|
|
312
|
+
" var rows = new List<string>();",
|
|
313
|
+
" EnumWindows((h, l) => {",
|
|
314
|
+
" if (!IsWindowVisible(h)) return true;",
|
|
315
|
+
" var t = new StringBuilder(512); GetWindowText(h, t, 512);",
|
|
316
|
+
" var c = new StringBuilder(256); GetClassName(h, c, 256);",
|
|
317
|
+
" uint pid = 0; GetWindowThreadProcessId(h, out pid);",
|
|
318
|
+
" IntPtr owner = GetWindow(h, (uint)4);",
|
|
319
|
+
' string cls = c.ToString().Replace("\\t"," ");',
|
|
320
|
+
' string title = t.ToString().Replace("\\t"," ").Replace("\\r"," ").Replace("\\n"," ");',
|
|
321
|
+
' rows.Add(h.ToInt64() + "\\t" + pid + "\\t" + owner.ToInt64() + "\\t" + (IsWindowEnabled(h) ? "1" : "0") + "\\t" + cls + "\\t" + title);',
|
|
322
|
+
" return true;",
|
|
323
|
+
" }, IntPtr.Zero);",
|
|
324
|
+
" return rows;",
|
|
325
|
+
" }",
|
|
326
|
+
" public static long Foreground() { return GetForegroundWindow().ToInt64(); }",
|
|
327
|
+
"}",
|
|
328
|
+
'"@',
|
|
329
|
+
"$rows = [ClModalEnum]::Rows()",
|
|
330
|
+
"$fg = [ClModalEnum]::Foreground()",
|
|
232
331
|
"$result = @()",
|
|
233
|
-
"foreach ($
|
|
234
|
-
|
|
235
|
-
" $
|
|
236
|
-
" $hwnd = $
|
|
237
|
-
" $procId = 0",
|
|
238
|
-
" try { $procId = $w.Current.ProcessId } catch { }",
|
|
239
|
-
" $isModal = $false",
|
|
240
|
-
" try {",
|
|
241
|
-
" $pattern = $w.GetCurrentPattern([System.Windows.Automation.WindowPattern]::Pattern)",
|
|
242
|
-
" $isModal = $pattern.Current.IsModal",
|
|
243
|
-
" } catch { }",
|
|
244
|
-
" $result += @{ name = $name; class_name = $cls; hwnd = $hwnd; is_modal = $isModal; process_id = $procId }",
|
|
332
|
+
"foreach ($r in $rows) {",
|
|
333
|
+
' $f = $r -split "`t", 6',
|
|
334
|
+
" if ($f.Length -lt 6) { continue }",
|
|
335
|
+
" $result += @{ hwnd = [int64]$f[0]; process_id = [int]$f[1]; owner_hwnd = [int64]$f[2]; is_enabled = ($f[3] -eq '1'); class_name = $f[4]; name = $f[5]; is_visible = $true }",
|
|
245
336
|
"}",
|
|
246
337
|
`$appTarget = '${psLiteral}'`,
|
|
247
338
|
"$appNorm = ($appTarget -replace '\\s','').ToLowerInvariant()",
|
|
@@ -252,10 +343,10 @@ async function detectWindowsModal(opts) {
|
|
|
252
343
|
" $appPids = @($apps | Select-Object -ExpandProperty Id)",
|
|
253
344
|
" $appMain = @($apps | ForEach-Object { [int64]$_.MainWindowHandle })",
|
|
254
345
|
"}",
|
|
255
|
-
"$out = @{ windows = @($result); app_pids = @($appPids); app_main_hwnds = @($appMain) }",
|
|
346
|
+
"$out = @{ windows = @($result); app_pids = @($appPids); app_main_hwnds = @($appMain); foreground_hwnd = $fg }",
|
|
256
347
|
"$out | ConvertTo-Json -Compress -Depth 5",
|
|
257
348
|
].join("\n");
|
|
258
|
-
const r = await runCommand("powershell", ["-NoProfile", "-Command", script], opts.cwd, undefined, undefined,
|
|
349
|
+
const r = await runCommand("powershell", ["-NoProfile", "-Command", script], opts.cwd, undefined, undefined, 12000);
|
|
259
350
|
if (r.exit_code !== 0) {
|
|
260
351
|
return {
|
|
261
352
|
is_modal_present: false,
|
|
@@ -272,6 +363,8 @@ async function detectWindowsModal(opts) {
|
|
|
272
363
|
probe.windows = asArr(p.windows);
|
|
273
364
|
probe.app_pids = asArr(p.app_pids).map((x) => Number(x));
|
|
274
365
|
probe.app_main_hwnds = asArr(p.app_main_hwnds);
|
|
366
|
+
if (p.foreground_hwnd != null)
|
|
367
|
+
probe.foreground_hwnd = p.foreground_hwnd;
|
|
275
368
|
}
|
|
276
369
|
}
|
|
277
370
|
catch {
|