@optima-chat/browser-cli 0.18.1 → 0.19.0

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.
Files changed (2) hide show
  1. package/dist/index.js +57 -11
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -785,6 +785,34 @@ import { tmpdir } from "os";
785
785
  import { basename, dirname, isAbsolute, join as join3, relative, resolve } from "path";
786
786
  var POLL_INTERVAL_MS = 2e3;
787
787
  var POLL_TIMEOUT_MS = 18e4;
788
+ var WAIT_DEFAULT_TIMEOUT_S = 90;
789
+ var WAIT_MAX_TIMEOUT_S = 570;
790
+ var EXIT_TASK_STOPPED = 2;
791
+ var EXIT_STILL_RUNNING = 3;
792
+ async function waitForScriptTask(taskId, timeoutMs, first) {
793
+ const deadline = Date.now() + timeoutMs;
794
+ let task = first ?? await api.getScriptTask(taskId);
795
+ while (task.status === "running") {
796
+ const left = deadline - Date.now();
797
+ if (left <= 0) return { task, timedOut: true };
798
+ await sleep(Math.min(POLL_INTERVAL_MS, left));
799
+ task = await api.getScriptTask(taskId);
800
+ }
801
+ return { task, timedOut: false };
802
+ }
803
+ function parseWaitTimeout(raw) {
804
+ const n = Number(raw);
805
+ if (!/^\d+$/.test(raw.trim()) || !Number.isInteger(n) || n < 1 || n > WAIT_MAX_TIMEOUT_S) {
806
+ throw new Error(`--timeout \u987B\u4E3A 1\u2013${WAIT_MAX_TIMEOUT_S} \u7684\u6574\u6570\u79D2(bash \u786C\u4E0A\u9650 600s),\u6536\u5230 ${JSON.stringify(raw)}`);
807
+ }
808
+ return n;
809
+ }
810
+ function stillRunningMessage(task, waitedS, nowMs = Date.now()) {
811
+ const started = task.created_at ? Date.parse(task.created_at) : Number.NaN;
812
+ const elapsed = Number.isFinite(started) ? `running for ${Math.max(0, Math.round((nowMs - started) / 1e3))}s` : `waited ${waitedS}s`;
813
+ const step = task.total_steps ? `, step ${task.current_step}/${task.total_steps}` : "";
814
+ return `Still running (${elapsed}${step}). Call again as a separate command: browser-cli script-task ${task.id} --wait`;
815
+ }
788
816
  var REQUIRED_ARG_FLAG = {
789
817
  ziniao_profile_id: "--ziniao-profile <id>",
790
818
  bitbrowser_profile_id: "--bitbrowser-profile <id>",
@@ -1018,18 +1046,13 @@ function registerScriptCommands(program2) {
1018
1046
  const task = await api.runScript(name, params, opts.connector, opts.ziniaoProfile, opts.bitbrowserProfile, opts.feikuaProfile, opts.chromeProfile);
1019
1047
  console.log(`Script started (task: ${task.id})`);
1020
1048
  if (!opts.poll) {
1021
- console.log(`Poll with: browser-cli script-task ${task.id}`);
1049
+ console.log(`Wait with: browser-cli script-task ${task.id} --wait`);
1022
1050
  return;
1023
1051
  }
1024
- const deadline = Date.now() + POLL_TIMEOUT_MS;
1025
- let result = task;
1026
- while (result.status === "running" && Date.now() < deadline) {
1027
- await sleep(POLL_INTERVAL_MS);
1028
- result = await api.getScriptTask(task.id);
1029
- }
1030
- if (result.status === "running") {
1052
+ const { task: result, timedOut } = await waitForScriptTask(task.id, POLL_TIMEOUT_MS, task);
1053
+ if (timedOut) {
1031
1054
  console.log(`Polling timed out. Task ${task.id} still running.`);
1032
- console.log(`Poll with: browser-cli script-task ${task.id}`);
1055
+ console.log(`Wait with: browser-cli script-task ${task.id} --wait`);
1033
1056
  return;
1034
1057
  }
1035
1058
  if (result.status === "needs_fallback" && result.session_id) {
@@ -1059,20 +1082,42 @@ ${downloadHint(result)}`);
1059
1082
  process.exit(1);
1060
1083
  }
1061
1084
  });
1062
- program2.command("script-task").argument("<task-id>", "Task ID").description("Check script task status").option("--download [path]", "Save the task's exported file (default: ./<filename>)").option("--json", "Print the raw task (status / error / full output) as JSON").action(async (taskId, opts) => {
1085
+ program2.command("script-task").argument("<task-id>", "Task ID").description("Check script task status").option("--download [path]", "Save the task's exported file (default: ./<filename>)").option("--json", "Print the raw task (status / error / full output) as JSON").option(
1086
+ "--wait",
1087
+ `Block until the task finishes (completed / failed / needs_fallback), at most --timeout seconds. Exit code: 0 completed, 2 failed / needs_fallback, 3 still running (call again), 1 error`
1088
+ ).option("--timeout <seconds>", `With --wait: max seconds to wait (default ${WAIT_DEFAULT_TIMEOUT_S}, max ${WAIT_MAX_TIMEOUT_S})`).action(async (taskId, opts) => {
1063
1089
  try {
1064
1090
  if (opts.json && opts.download !== void 0) {
1065
1091
  throw new Error("--json \u4E0E --download \u53EA\u80FD\u7ED9\u4E00\u4E2A");
1066
1092
  }
1067
- const task = await api.getScriptTask(taskId);
1093
+ if (opts.timeout !== void 0 && !opts.wait) throw new Error("--timeout \u53EA\u80FD\u548C --wait \u4E00\u8D77\u7528");
1094
+ const timeoutS = opts.timeout === void 0 ? WAIT_DEFAULT_TIMEOUT_S : parseWaitTimeout(opts.timeout);
1095
+ let task;
1096
+ if (opts.wait) {
1097
+ const waited = await waitForScriptTask(taskId, timeoutS * 1e3);
1098
+ task = waited.task;
1099
+ if (waited.timedOut) {
1100
+ if (opts.json) console.log(JSON.stringify(task, null, 2));
1101
+ (opts.json ? console.error : console.log)(stillRunningMessage(task, timeoutS));
1102
+ process.exit(EXIT_STILL_RUNNING);
1103
+ return;
1104
+ }
1105
+ } else {
1106
+ task = await api.getScriptTask(taskId);
1107
+ }
1108
+ const stoppedExit = () => {
1109
+ if (opts.wait && task.status !== "completed") process.exit(EXIT_TASK_STOPPED);
1110
+ };
1068
1111
  if (task.status === "needs_fallback" && task.session_id) saveSessionId(task.session_id);
1069
1112
  if (opts.json) {
1070
1113
  console.log(JSON.stringify(task, null, 2));
1114
+ stoppedExit();
1071
1115
  return;
1072
1116
  }
1073
1117
  if (opts.download === void 0) {
1074
1118
  console.log(formatScriptTask(task));
1075
1119
  if (hasStagedArtifact(task)) console.log(downloadHint(task));
1120
+ stoppedExit();
1076
1121
  return;
1077
1122
  }
1078
1123
  if (task.status === "running") {
@@ -1081,6 +1126,7 @@ ${downloadHint(result)}`);
1081
1126
  const saved = await deliverArtifact(task, typeof opts.download === "string" ? opts.download : void 0);
1082
1127
  if (!saved) throw new Error(`Task ${taskId} produced no file`);
1083
1128
  console.log(`Saved -> ${saved.path}${saved.size === void 0 ? "" : ` (${saved.size} bytes)`}`);
1129
+ stoppedExit();
1084
1130
  } catch (err) {
1085
1131
  const gone = err.errorCode === "artifact_gone";
1086
1132
  console.error(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optima-chat/browser-cli",
3
- "version": "0.18.1",
3
+ "version": "0.19.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "bin": {