@proagentstore/cli 0.4.8 → 0.4.10

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.
@@ -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
@@ -84,6 +88,14 @@ export class LocalRunner {
84
88
  const normalized = normalizeCreateTaskRequest(request);
85
89
  validateTaskInput(normalized.type, normalized.input);
86
90
  const now = new Date().toISOString();
91
+ // Optional card presentation for the console kanban (only set when provided).
92
+ const card = {};
93
+ if (normalized.title)
94
+ card.title = normalized.title;
95
+ if (normalized.subtitle)
96
+ card.subtitle = normalized.subtitle;
97
+ if (normalized.description)
98
+ card.description = normalized.description;
87
99
  // Agent-driven applications are steered by the remote Workflow brain via the
88
100
  // /browser/* endpoints — the runner never auto-executes them. The task exists
89
101
  // for the console board, the activity trace, and takeover keying.
@@ -93,6 +105,7 @@ export class LocalRunner {
93
105
  type: normalized.type,
94
106
  status: "running",
95
107
  input: normalized.input,
108
+ ...card,
96
109
  requiresApproval: false,
97
110
  createdAt: now,
98
111
  updatedAt: now,
@@ -107,6 +120,7 @@ export class LocalRunner {
107
120
  type: normalized.type,
108
121
  status: requiresApproval ? "needs_approval" : "queued",
109
122
  input: normalized.input,
123
+ ...card,
110
124
  requiresApproval,
111
125
  approval: requiresApproval
112
126
  ? {
@@ -411,6 +425,9 @@ export class LocalRunner {
411
425
  return;
412
426
  this.fileAttachArmed.add(page);
413
427
  page.on("filechooser", (chooser) => {
428
+ // Skip when an explicit upload action is already attaching (avoids double-attach).
429
+ if (this.suppressAutoAttach)
430
+ return;
414
431
  chooser.setFiles(filePath).catch(() => undefined);
415
432
  });
416
433
  }
@@ -765,20 +782,28 @@ export class LocalRunner {
765
782
  throw new RunnerInputError("no résumé file available to upload");
766
783
  // Standard two-step FIRST (respects the brain's target): clicking the upload
767
784
  // control opens the file chooser → browser_file_upload attaches the résumé.
768
- const ref = (a.ref || "").trim();
769
- if (ref)
770
- await mcp.callTool("browser_click", { element: label, target: ref }).catch(() => undefined);
771
- const res = await mcp.callTool("browser_file_upload", { paths: [this.applyResumePath] });
772
- if (!res.isError || !/modal state|file chooser/i.test(mcp.textOf(res)))
773
- return res;
774
- // The target was a LABEL / DROP-ZONE, not the chooser trigger, so no file
775
- // chooser opened. Fall back to setting the résumé directly on the page's
776
- // file input — robust across hidden inputs, drop-zones and custom upload
777
- // widgets (the semantically-correct upload field the brain clicks is often
778
- // a container, not the button that fires the chooser).
779
- const page = await this.getActivePage();
780
- await page.locator('input[type="file"]').first().setInputFiles(this.applyResumePath, { timeout: 8_000 });
781
- return { content: [{ type: "text", text: "résumé attached directly to the file input" }] };
785
+ // Suppress the global auto-attach handler for the duration so the résumé isn't
786
+ // attached twice (the click below can itself open a chooser the handler grabs).
787
+ this.suppressAutoAttach = true;
788
+ try {
789
+ const ref = (a.ref || "").trim();
790
+ if (ref)
791
+ await mcp.callTool("browser_click", { element: label, target: ref }).catch(() => undefined);
792
+ const res = await mcp.callTool("browser_file_upload", { paths: [this.applyResumePath] });
793
+ if (!res.isError || !/modal state|file chooser/i.test(mcp.textOf(res)))
794
+ return res;
795
+ // The target was a LABEL / DROP-ZONE, not the chooser trigger, so no file
796
+ // chooser opened. Fall back to setting the résumé directly on the page's
797
+ // file input — robust across hidden inputs, drop-zones and custom upload
798
+ // widgets (the semantically-correct upload field the brain clicks is often
799
+ // a container, not the button that fires the chooser).
800
+ const page = await this.getActivePage();
801
+ await page.locator('input[type="file"]').first().setInputFiles(this.applyResumePath, { timeout: 8_000 });
802
+ return { content: [{ type: "text", text: "résumé attached directly to the file input" }] };
803
+ }
804
+ finally {
805
+ this.suppressAutoAttach = false;
806
+ }
782
807
  }
783
808
  case "select":
784
809
  return mcp.callTool("browser_select_option", { element: label, target: this.refOf(a), values: [a.text ?? ""] });
@@ -1052,9 +1077,13 @@ function normalizeCreateTaskRequest(request) {
1052
1077
  if (!isRecord(request) || typeof request.type !== "string" || !request.type.trim()) {
1053
1078
  throw new RunnerInputError("task type required");
1054
1079
  }
1080
+ const str = (v, max) => (typeof v === "string" ? v.trim().slice(0, max) : "");
1055
1081
  return {
1056
1082
  type: request.type.trim().slice(0, 120),
1057
1083
  input: isRecord(request.input) ? request.input : {},
1084
+ title: str(request.title, 200),
1085
+ subtitle: str(request.subtitle, 200),
1086
+ description: str(request.description, 500),
1058
1087
  requiresApproval: request.requiresApproval === true,
1059
1088
  approvalPrompt: typeof request.approvalPrompt === "string"
1060
1089
  ? request.approvalPrompt.trim().slice(0, 500)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proagentstore/cli",
3
- "version": "0.4.8",
3
+ "version": "0.4.10",
4
4
  "description": "CLI for creating, publishing, and running ProAgentStore agents",
5
5
  "license": "MIT",
6
6
  "type": "module",