@proagentstore/cli 0.4.134 → 0.4.135

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.
@@ -94,6 +94,7 @@ export const INSPECT_PAGE = `() => {
94
94
  unavailable: new RegExp(UNAVAILABLE_TEXT_SOURCE, "i").test(text) ? (new RegExp(EXPIRED_TEXT_SOURCE, "i").test(text) ? "expired" : "unavailable") : null,
95
95
  };
96
96
  }`;
97
+ const signInQuestion = (site) => `Sign in to ${site} on this machine's application browser, then retry. Nothing was submitted.`;
97
98
  const text = (t, isError = false) => ({ content: [{ type: "text", text: t }], ...(isError ? { isError: true } : {}) });
98
99
  const textOf = (r) => (r.content ?? []).map((c) => c.text ?? "").join("\n");
99
100
  const escapeRe = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -283,7 +284,9 @@ export class ApplyBridge {
283
284
  if (!v || typeof v.url !== "string")
284
285
  return null;
285
286
  const unavailable = v.unavailable === "expired" || v.unavailable === "unavailable" ? v.unavailable : null;
286
- return { url: v.url, title: String(v.title ?? ""), captcha: !!v.captcha, login: !!v.login, duplicate: !!v.duplicate, antiBot: !!v.antiBot, confirmed: !!v.confirmed, unavailable };
287
+ // A sign-in page by its ADDRESS too (#1100): SEEK's `login.seek.com/login` has no password field, so an
288
+ // "Apply" that bounced there ran on to `awaiting_review` with nothing filled. Same rule as the submit path.
289
+ return { url: v.url, title: String(v.title ?? ""), captcha: !!v.captcha, login: looksLikeSignIn(v.url, !!v.login), duplicate: !!v.duplicate, antiBot: !!v.antiBot, confirmed: !!v.confirmed, unavailable };
287
290
  }
288
291
  blockerOf(s) {
289
292
  return s.captcha ? "captcha" : s.antiBot ? "anti_bot" : s.duplicate ? "duplicate_application" : s.login ? "login_required" : null;
@@ -314,15 +317,19 @@ export class ApplyBridge {
314
317
  const blocker = this.blockerOf(state);
315
318
  if (!blocker)
316
319
  return text(toolText);
320
+ return this.holdFor(blocker, state);
321
+ }
322
+ /** A page that needs a person: pause for the owner, and remember a sign-in they complete (#1094). */
323
+ async holdFor(blocker, state) {
324
+ const host = hostOf(state.url) ?? "";
317
325
  this.host.emit({ type: "browser.blocked", url: state.url, domain: host, detail: { reason: blocker } });
318
326
  const site = blocker === "login_required" && host ? siteKeyOf(host) : null;
319
327
  if (site)
320
328
  await this.host.sessions?.beginSignIn(site).catch(() => undefined);
321
- const ok = await this.pauseFor({ reason: blocker, url: state.url, domain: host }, async () => {
329
+ const ok = await this.pauseFor({ reason: blocker, url: state.url, domain: host, ...(site ? { question: signInQuestion(site) } : {}) }, async () => {
322
330
  const after = await this.inspect();
323
331
  return !!after && this.blockerOf(after) === null;
324
332
  });
325
- // A sign-in the owner completed here is remembered for this browser profile (#1094).
326
333
  if (ok && site)
327
334
  await this.recordSignIn(site);
328
335
  if (!ok)
@@ -533,6 +540,12 @@ export class ApplyBridge {
533
540
  if (!phase)
534
541
  return text("supervisor_checkpoint needs phase initial, post_navigation, before_submit or uncertain.", true);
535
542
  const state = await this.inspect();
543
+ // A sign-in reached after the last landing — a late redirect (#1100, run 804bed49): hold for the owner as
544
+ // on landing. Reported to the cloud as a blocker it was stopped, and ended `incomplete`.
545
+ if (state?.login && !this.blocked) {
546
+ const held = await this.holdFor("login_required", state);
547
+ return held.isError ? held : text("The owner signed in. Take a browser_snapshot to read the page, then call supervisor_checkpoint again.");
548
+ }
536
549
  const blockers = new Set();
537
550
  if (state?.captcha)
538
551
  blockers.add("captcha");
@@ -588,8 +601,16 @@ export class ApplyBridge {
588
601
  this.host.emit({ type: "job.unavailable", url, domain, detail: { reason, source: "page_notice" } });
589
602
  return text(`Recorded the runner-verified ${reason} listing notice. Stop now.`);
590
603
  }
591
- review(summary) {
604
+ async review(summary) {
592
605
  this.summary = summary; // bounded where the result is built (runtime.ts `end`)
606
+ // Nothing entered, on a sign-in page (#1100; runs abb37433, 7fb1e4f5): the outcome is the owner's sign-in,
607
+ // not an empty form "awaiting review" — a card that is not `login_required` offers them no sign-in at all.
608
+ const state = !this.filled && !this.uploaded.size && !this.blocked ? await this.inspect() : null;
609
+ const host = state?.login ? hostOf(state.url) : null;
610
+ if (state && host) {
611
+ this.host.emit({ type: "browser.blocked", url: state.url, domain: host, detail: { reason: "login_required" } });
612
+ this.blocked = { reason: "login_required", questions: [signInQuestion(siteKeyOf(host))] };
613
+ }
593
614
  // #989: "ready for review" with nothing entered is not a review state.
594
615
  //
595
616
  // The live run ended `awaiting_review` with `filled: 0, uploaded: 0` seconds after the cloud
@@ -655,7 +676,7 @@ export class ApplyBridge {
655
676
  ],
656
677
  };
657
678
  }
658
- this.review(oneClick ? "Stopped at a one-click apply control: it can send the application outright, and this run fills and waits for review." : "Stopped at the final submit: this run fills and waits for review.");
679
+ await this.review(oneClick ? "Stopped at a one-click apply control: it can send the application outright, and this run fills and waits for review." : "Stopped at the final submit: this run fills and waits for review.");
659
680
  return text(oneClick
660
681
  ? 'That control ("' + String(forward.element ?? "") + '") can send the application in one click, and this run is fill-and-review: it was NOT pressed. Approve this application if you want it sent. Stop now.'
661
682
  : "That control submits the application, and this run is fill-and-review: it was NOT pressed. The application waits for the owner's review. Stop now.");
@@ -37,39 +37,6 @@ export const LOCAL_APPLY_CANCEL_PATH = "/local-apply/cancel";
37
37
  export const LOCAL_APPLY_PREFLIGHT_PATH = "/local-apply/preflight";
38
38
  /** Delivers a cloud-persisted supervisory decision to one paused checkpoint. */
39
39
  export const LOCAL_APPLY_DIRECTIVE_PATH = "/local-apply/directive";
40
- /**
41
- * A short-lived, owner-authorized view of the *existing* browser page for one local-apply run.
42
- * The id is opaque and carries no browser/profile material. It deliberately is not a task id:
43
- * local-apply runs are not generic runner tasks.
44
- */
45
- export const LOCAL_APPLY_HANDOFF_PATH = "/local-apply/handoff";
46
- export const LOCAL_APPLY_HANDOFF_STATUS_PATH = "/local-apply/handoff-status";
47
- export const LOCAL_APPLY_HANDOFF_FRAME_PATH = "/local-apply/handoff/frame";
48
- export const LOCAL_APPLY_HANDOFF_INPUT_PATH = "/local-apply/handoff/input";
49
- export const LOCAL_APPLY_HANDOFF_RESUME_PATH = "/local-apply/handoff/resume";
50
- export const LOCAL_APPLY_HANDOFF_END_PATH = "/local-apply/handoff/end";
51
- /**
52
- * A separate, browser-only receipt/history check for an already-ended uncertain attempt. This is
53
- * deliberately not an application run: it receives no engine, sources, artifacts or submit gate.
54
- */
55
- export const LOCAL_APPLY_RECONCILIATION_RUN_PATH = "/local-apply/reconciliation/run";
56
- export const LOCAL_APPLY_RECONCILIATION_STATUS_PATH = "/local-apply/reconciliation/status";
57
- export const LOCAL_APPLY_RECONCILIATION_HANDOFF_PATH = "/local-apply/reconciliation/handoff";
58
- export const LOCAL_APPLY_RECONCILIATION_HANDOFF_STATUS_PATH = "/local-apply/reconciliation/handoff-status";
59
- export const LOCAL_APPLY_RECONCILIATION_HANDOFF_FRAME_PATH = "/local-apply/reconciliation/handoff/frame";
60
- export const LOCAL_APPLY_RECONCILIATION_HANDOFF_INPUT_PATH = "/local-apply/reconciliation/handoff/input";
61
- export const LOCAL_APPLY_RECONCILIATION_HANDOFF_RESUME_PATH = "/local-apply/reconciliation/handoff/resume";
62
- export const LOCAL_APPLY_RECONCILIATION_HANDOFF_END_PATH = "/local-apply/reconciliation/handoff/end";
63
- /**
64
- * A sign-in to the job's site in this machine's application browser profile, AFTER a fill ended
65
- * `blocked` on `login_required` (#1100). Not a run and not a run's handoff: there is no engine, no
66
- * source, no artifact and no submit gate — only the profile's page at the job's site, for the owner
67
- * to sign in, and the profile's sign-in ledger (#1094) to record that they did.
68
- */
69
- export const LOCAL_APPLY_SIGN_IN_PATH = "/local-apply/sign-in";
70
- export const LOCAL_APPLY_SIGN_IN_FRAME_PATH = "/local-apply/sign-in/frame";
71
- export const LOCAL_APPLY_SIGN_IN_INPUT_PATH = "/local-apply/sign-in/input";
72
- export const LOCAL_APPLY_SIGN_IN_END_PATH = "/local-apply/sign-in/end";
73
40
  export const LOCAL_APPLY_ENGINES = ["claude", "codex"];
74
41
  export const LOCAL_APPLY_AUTH_MODES = ["machine", "subscription"];
75
42
  export const LOCAL_APPLY_MODES = ["fill_and_review", "auto_submit"];
@@ -176,7 +143,6 @@ export const LOCAL_APPLY_EVENT_TYPES = [
176
143
  export const LOCAL_APPLY_ENGINE_AUTHS = ["machine-login", "subscription", "api-key", "missing_login", "unknown"];
177
144
  export const LOCAL_APPLY_SUPERVISOR_DIRECTIVES = ["continue", "request_review", "stop"];
178
145
  export const LOCAL_APPLY_SUPERVISOR_PHASES = ["initial", "before_submit", "post_navigation", "uncertain"];
179
- export const LOCAL_APPLY_HANDOFF_TERMINAL_REASONS = ["unavailable", "profile_unavailable", "profile_mismatch", "page_lost", "expired", "run_ended", "runner_restarted"];
180
146
  export const LOCAL_APPLY_CAPS = { questions: 20, questionChars: 300, answers: 20, answerChars: 2000, summary: 2000 };
181
147
  const str = (v, max) => (typeof v === "string" && v.trim() ? v.trim().slice(0, max) : null);
182
148
  const oneOf = (list, v) => (list.includes(v) ? v : null);
@@ -0,0 +1,34 @@
1
+ /**
2
+ * A short-lived, owner-authorized view of the *existing* browser page for one local-apply run.
3
+ * The id is opaque and carries no browser/profile material. It deliberately is not a task id:
4
+ * local-apply runs are not generic runner tasks.
5
+ */
6
+ export const LOCAL_APPLY_HANDOFF_PATH = "/local-apply/handoff";
7
+ export const LOCAL_APPLY_HANDOFF_STATUS_PATH = "/local-apply/handoff-status";
8
+ export const LOCAL_APPLY_HANDOFF_FRAME_PATH = "/local-apply/handoff/frame";
9
+ export const LOCAL_APPLY_HANDOFF_INPUT_PATH = "/local-apply/handoff/input";
10
+ export const LOCAL_APPLY_HANDOFF_RESUME_PATH = "/local-apply/handoff/resume";
11
+ export const LOCAL_APPLY_HANDOFF_END_PATH = "/local-apply/handoff/end";
12
+ /**
13
+ * A separate, browser-only receipt/history check for an already-ended uncertain attempt. This is
14
+ * deliberately not an application run: it receives no engine, sources, artifacts or submit gate.
15
+ */
16
+ export const LOCAL_APPLY_RECONCILIATION_RUN_PATH = "/local-apply/reconciliation/run";
17
+ export const LOCAL_APPLY_RECONCILIATION_STATUS_PATH = "/local-apply/reconciliation/status";
18
+ export const LOCAL_APPLY_RECONCILIATION_HANDOFF_PATH = "/local-apply/reconciliation/handoff";
19
+ export const LOCAL_APPLY_RECONCILIATION_HANDOFF_STATUS_PATH = "/local-apply/reconciliation/handoff-status";
20
+ export const LOCAL_APPLY_RECONCILIATION_HANDOFF_FRAME_PATH = "/local-apply/reconciliation/handoff/frame";
21
+ export const LOCAL_APPLY_RECONCILIATION_HANDOFF_INPUT_PATH = "/local-apply/reconciliation/handoff/input";
22
+ export const LOCAL_APPLY_RECONCILIATION_HANDOFF_RESUME_PATH = "/local-apply/reconciliation/handoff/resume";
23
+ export const LOCAL_APPLY_RECONCILIATION_HANDOFF_END_PATH = "/local-apply/reconciliation/handoff/end";
24
+ /**
25
+ * A sign-in to the job's site in this machine's application browser profile, AFTER a fill ended
26
+ * `blocked` on `login_required` (#1100). Not a run and not a run's handoff: there is no engine, no
27
+ * source, no artifact and no submit gate — only the profile's page at the job's site, for the owner
28
+ * to sign in, and the profile's sign-in ledger (#1094) to record that they did.
29
+ */
30
+ export const LOCAL_APPLY_SIGN_IN_PATH = "/local-apply/sign-in";
31
+ export const LOCAL_APPLY_SIGN_IN_FRAME_PATH = "/local-apply/sign-in/frame";
32
+ export const LOCAL_APPLY_SIGN_IN_INPUT_PATH = "/local-apply/sign-in/input";
33
+ export const LOCAL_APPLY_SIGN_IN_END_PATH = "/local-apply/sign-in/end";
34
+ export const LOCAL_APPLY_HANDOFF_TERMINAL_REASONS = ["unavailable", "profile_unavailable", "profile_mismatch", "page_lost", "expired", "run_ended", "runner_restarted"];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proagentstore/cli",
3
- "version": "0.4.134",
3
+ "version": "0.4.135",
4
4
  "description": "CLI for creating, publishing, and running ProAgentStore agents",
5
5
  "license": "MIT",
6
6
  "type": "module",