@proagentstore/cli 0.4.8 → 0.4.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.
- package/dist/browser-runner/runner.js +29 -14
- package/package.json +1 -1
|
@@ -41,6 +41,10 @@ export class LocalRunner {
|
|
|
41
41
|
*/
|
|
42
42
|
activePage = null;
|
|
43
43
|
fileAttachArmed = new WeakSet();
|
|
44
|
+
// When the explicit `upload` action is driving a chooser itself (browser_file_upload),
|
|
45
|
+
// suppress the global auto-attach handler so the résumé isn't attached TWICE (the click
|
|
46
|
+
// that opens the chooser would otherwise trigger both auto-attach AND browser_file_upload).
|
|
47
|
+
suppressAutoAttach = false;
|
|
44
48
|
applyResumePath = null;
|
|
45
49
|
/**
|
|
46
50
|
* The INDUSTRY-STANDARD `@playwright/mcp` server, attached over CDP to the same
|
|
@@ -411,6 +415,9 @@ export class LocalRunner {
|
|
|
411
415
|
return;
|
|
412
416
|
this.fileAttachArmed.add(page);
|
|
413
417
|
page.on("filechooser", (chooser) => {
|
|
418
|
+
// Skip when an explicit upload action is already attaching (avoids double-attach).
|
|
419
|
+
if (this.suppressAutoAttach)
|
|
420
|
+
return;
|
|
414
421
|
chooser.setFiles(filePath).catch(() => undefined);
|
|
415
422
|
});
|
|
416
423
|
}
|
|
@@ -765,20 +772,28 @@ export class LocalRunner {
|
|
|
765
772
|
throw new RunnerInputError("no résumé file available to upload");
|
|
766
773
|
// Standard two-step FIRST (respects the brain's target): clicking the upload
|
|
767
774
|
// control opens the file chooser → browser_file_upload attaches the résumé.
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
775
|
+
// Suppress the global auto-attach handler for the duration so the résumé isn't
|
|
776
|
+
// attached twice (the click below can itself open a chooser the handler grabs).
|
|
777
|
+
this.suppressAutoAttach = true;
|
|
778
|
+
try {
|
|
779
|
+
const ref = (a.ref || "").trim();
|
|
780
|
+
if (ref)
|
|
781
|
+
await mcp.callTool("browser_click", { element: label, target: ref }).catch(() => undefined);
|
|
782
|
+
const res = await mcp.callTool("browser_file_upload", { paths: [this.applyResumePath] });
|
|
783
|
+
if (!res.isError || !/modal state|file chooser/i.test(mcp.textOf(res)))
|
|
784
|
+
return res;
|
|
785
|
+
// The target was a LABEL / DROP-ZONE, not the chooser trigger, so no file
|
|
786
|
+
// chooser opened. Fall back to setting the résumé directly on the page's
|
|
787
|
+
// file input — robust across hidden inputs, drop-zones and custom upload
|
|
788
|
+
// widgets (the semantically-correct upload field the brain clicks is often
|
|
789
|
+
// a container, not the button that fires the chooser).
|
|
790
|
+
const page = await this.getActivePage();
|
|
791
|
+
await page.locator('input[type="file"]').first().setInputFiles(this.applyResumePath, { timeout: 8_000 });
|
|
792
|
+
return { content: [{ type: "text", text: "résumé attached directly to the file input" }] };
|
|
793
|
+
}
|
|
794
|
+
finally {
|
|
795
|
+
this.suppressAutoAttach = false;
|
|
796
|
+
}
|
|
782
797
|
}
|
|
783
798
|
case "select":
|
|
784
799
|
return mcp.callTool("browser_select_option", { element: label, target: this.refOf(a), values: [a.text ?? ""] });
|