@proagentstore/cli 0.3.0 → 0.3.1

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.
@@ -377,7 +377,9 @@ export class LocalRunner {
377
377
  this.store.putTask(task);
378
378
  this.addTaskEvent(task, "task.completed", `Task completed: ${task.type}`, output);
379
379
  await this.endTakeover(taskId);
380
- return { submitted: true, output };
380
+ // This path only CLEARED a challenge — the form was NOT submitted (output.submitted
381
+ // is false). Report it accurately so the console doesn't show a false "submitted".
382
+ return { submitted: false, resumed: true, output };
381
383
  }
382
384
  /**
383
385
  * Always attach files via Playwright, never a native OS dialog: intercept any
@@ -584,6 +586,19 @@ export class LocalRunner {
584
586
  }
585
587
  });
586
588
  }
589
+ /** Close every page except the active one. ATS forms open popups/extra tabs that
590
+ * otherwise stay open in the persistent context until shutdown; over many
591
+ * applications they accumulate (memory/handles). Called when a task finishes. */
592
+ async closeStalePages() {
593
+ const ctx = this.browserContext;
594
+ if (!ctx)
595
+ return;
596
+ for (const p of ctx.pages()) {
597
+ if (p !== this.activePage && !p.isClosed()) {
598
+ await p.close().catch(() => undefined);
599
+ }
600
+ }
601
+ }
587
602
  /** The page the brain drives and the human takes over — created on demand. */
588
603
  async getActivePage() {
589
604
  const context = await this.getBrowserContext();
@@ -716,28 +731,39 @@ export class LocalRunner {
716
731
  /** Whether the brain can resume: a solved captcha (auto), a human "Resume" for a stuck step, or a provided value. */
717
732
  async browserHandoffStatus(taskId) {
718
733
  const session = this.takeovers.get(taskId);
719
- const page = session?.page ?? (await this.getActivePage());
734
+ // No live takeover session (the runner restarted mid-handoff, or it expired): stay
735
+ // UNRESOLVED. The old code fell through and relaunched a blank page via
736
+ // getActivePage(), which detected no challenge and reported solved:true — so the
737
+ // brain resumed the application WITHOUT the human's captcha/value. A status poll
738
+ // must never relaunch the browser or claim a lost handoff is done.
739
+ if (!session)
740
+ return { solved: false, challenge: null };
741
+ const page = session.page;
720
742
  if (page.isClosed())
721
743
  return { solved: true, challenge: null };
722
744
  // A needs_input handoff resumes once the user supplies the value.
723
- if (session?.reason === "needs_input")
745
+ if (session.reason === "needs_input")
724
746
  return { solved: !!session.inputValue, challenge: null, value: session.inputValue };
725
747
  // A stuck handoff resumes only when the human explicitly clicks Resume —
726
748
  // there's nothing to auto-detect.
727
- if (session?.reason === "stuck")
749
+ if (session.reason === "stuck")
728
750
  return { solved: !!session.humanDone, challenge: null };
729
751
  // A challenge resumes when the token/widget clears OR the human clicks Done —
730
752
  // custom captchas (e.g. PageUp's "not a robot") have no detectable token, so
731
753
  // the human's explicit Done is the authority; never strand them.
732
754
  const challenge = await detectHumanChallenge(page);
733
- const solved = !challenge || (await challengeSolved(page)) || !!session?.humanDone;
755
+ const solved = !challenge || (await challengeSolved(page)) || !!session.humanDone;
734
756
  return { solved, challenge };
735
757
  }
736
758
  /** The user supplied the value the agent asked for (ask-and-hold). */
737
759
  browserSubmitInput(taskId, value) {
738
760
  const session = this.takeovers.get(taskId);
739
- if (session)
740
- session.inputValue = value;
761
+ // No live takeover (session expired / runner restarted): the value can't be
762
+ // delivered. Don't discard it silently AND resurrect the already-terminal task as
763
+ // "running" — report failure so the console can say "session expired, re-run".
764
+ if (!session)
765
+ return { ok: false };
766
+ session.inputValue = value;
741
767
  const task = this.store.getTask(taskId);
742
768
  if (task) {
743
769
  task.status = "running";
@@ -777,6 +803,7 @@ export class LocalRunner {
777
803
  this.store.putTask(task);
778
804
  this.addTaskEvent(task, success ? "task.completed" : "task.failed", detail || `Application ${outcome}`, { outcome, detail });
779
805
  }
806
+ await this.closeStalePages().catch(() => undefined);
780
807
  return { ok: true };
781
808
  }
782
809
  ensureChromiumInstalled() {
package/dist/index.js CHANGED
@@ -171,6 +171,7 @@ var initCommand = new Command2("init").description("Scaffold a new ProAgentStore
171
171
  category: "general",
172
172
  model: "@cf/meta/llama-3.2-3b-instruct",
173
173
  template,
174
+ capabilities: { surfaces: [], runtime: null, workflow: null },
174
175
  serverConfig: {
175
176
  durableObject: template === "worker",
176
177
  cron: template === "cron" ? "0 8 * * *" : void 0,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proagentstore/cli",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "CLI for creating, publishing, and running ProAgentStore agents",
5
5
  "license": "MIT",
6
6
  "type": "module",