@optima-chat/browser-cli 0.8.0 → 0.9.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.
- package/dist/index.js +56 -53
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -186,14 +186,6 @@ var BrowserAPI = class {
|
|
|
186
186
|
body: JSON.stringify(body)
|
|
187
187
|
});
|
|
188
188
|
}
|
|
189
|
-
async listProfiles() {
|
|
190
|
-
return request("/api/profiles");
|
|
191
|
-
}
|
|
192
|
-
async deleteProfile(profileId) {
|
|
193
|
-
return request("/api/profiles/" + encodeURIComponent(profileId), {
|
|
194
|
-
method: "DELETE"
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
189
|
async setZiNiaoConfig(company, username, password) {
|
|
198
190
|
return request("/api/user/ziniao-config", {
|
|
199
191
|
method: "PUT",
|
|
@@ -265,7 +257,14 @@ var BrowserAPI = class {
|
|
|
265
257
|
const deadline = Date.now() + timeoutMs;
|
|
266
258
|
for (; ; ) {
|
|
267
259
|
const task = await request(`/api/script-tasks/${started.id}`);
|
|
268
|
-
if (task.status === "completed")
|
|
260
|
+
if (task.status === "completed") {
|
|
261
|
+
if (!task.output) {
|
|
262
|
+
throw new Error(
|
|
263
|
+
`recipe ${name} reported completed but returned no output (task ${started.id})`
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
return task.output;
|
|
267
|
+
}
|
|
269
268
|
if (task.status === "failed" || task.status === "needs_fallback") {
|
|
270
269
|
throw new Error(task.error || task.output?.error || `recipe ${task.status}`);
|
|
271
270
|
}
|
|
@@ -452,20 +451,6 @@ function formatError(err) {
|
|
|
452
451
|
function formatTabsInline(tabs) {
|
|
453
452
|
return tabs.map((t) => `[${t.tab_id}] ${t.title}`).join(", ");
|
|
454
453
|
}
|
|
455
|
-
function formatProfiles(result) {
|
|
456
|
-
if (result.profiles.length === 0) {
|
|
457
|
-
return "No browser profiles found.";
|
|
458
|
-
}
|
|
459
|
-
const lines = result.profiles.map((p) => {
|
|
460
|
-
const sizeMb = (p.size_bytes / (1024 * 1024)).toFixed(1);
|
|
461
|
-
return ` ${p.profile_id} (${sizeMb} MB)`;
|
|
462
|
-
});
|
|
463
|
-
return `Browser profiles:
|
|
464
|
-
${lines.join("\n")}`;
|
|
465
|
-
}
|
|
466
|
-
function formatProfileDelete(profileId) {
|
|
467
|
-
return `Profile '${profileId}' deleted.`;
|
|
468
|
-
}
|
|
469
454
|
|
|
470
455
|
// src/commands/lifecycle.ts
|
|
471
456
|
function registerLifecycleCommands(program2) {
|
|
@@ -688,15 +673,38 @@ function registerTabCommands(program2) {
|
|
|
688
673
|
}
|
|
689
674
|
|
|
690
675
|
// src/commands/script.ts
|
|
691
|
-
import { readFileSync as readFileSync3 } from "fs";
|
|
676
|
+
import { mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
677
|
+
import { basename, dirname, resolve } from "path";
|
|
692
678
|
var POLL_INTERVAL_MS = 2e3;
|
|
693
679
|
var POLL_TIMEOUT_MS = 18e4;
|
|
680
|
+
var REQUIRED_ARG_FLAG = {
|
|
681
|
+
ziniao_profile_id: "--ziniao-profile <id>",
|
|
682
|
+
bitbrowser_profile_id: "--bitbrowser-profile <id>"
|
|
683
|
+
};
|
|
684
|
+
function formatRequiredArgs(s) {
|
|
685
|
+
if (!s.required_args?.length) return null;
|
|
686
|
+
const flags = s.required_args.map((a) => REQUIRED_ARG_FLAG[a] ?? `--param ${a}=<value>`).join(" ");
|
|
687
|
+
return ` requires: ${flags}`;
|
|
688
|
+
}
|
|
689
|
+
async function deliverArtifact(task, out) {
|
|
690
|
+
const output = task.output;
|
|
691
|
+
if (!output) return null;
|
|
692
|
+
if (output.path) return output.path;
|
|
693
|
+
if (!output.artifact_path) return null;
|
|
694
|
+
const target = resolve(out ?? `./${basename(output.filename ?? "artifact")}`);
|
|
695
|
+
const content = await api.fetchArtifact(output.artifact_path);
|
|
696
|
+
mkdirSync2(dirname(target), { recursive: true });
|
|
697
|
+
writeFileSync3(target, content);
|
|
698
|
+
return target;
|
|
699
|
+
}
|
|
694
700
|
function formatScriptList(scripts) {
|
|
695
701
|
if (scripts.length === 0) return "No scripts registered.";
|
|
696
702
|
const lines = [];
|
|
697
703
|
for (const s of scripts) {
|
|
698
704
|
const tag = s.source ? ` [${s.source}]` : "";
|
|
699
705
|
lines.push(`${s.name} \u2014 ${s.description}${tag}`);
|
|
706
|
+
const requires = formatRequiredArgs(s);
|
|
707
|
+
if (requires) lines.push(requires);
|
|
700
708
|
for (let i = 0; i < s.steps.length; i++) {
|
|
701
709
|
lines.push(` [${i + 1}] ${s.steps[i].id} \u2014 ${s.steps[i].description}`);
|
|
702
710
|
}
|
|
@@ -787,7 +795,7 @@ function registerScriptCommands(program2) {
|
|
|
787
795
|
process.exit(1);
|
|
788
796
|
}
|
|
789
797
|
});
|
|
790
|
-
program2.command("runscript").argument("<name>", "Script name").description("Run a script (polls until complete)").option("--param <params...>", "Parameters as key=value").option("--connector <type>", "Browser connector: chrome, ziniao, or bitbrowser").option("--ziniao-profile <id>", "ZiNiao browser profile ID (with --connector ziniao)").option("--bitbrowser-profile <id>", "BitBrowser profile ID (with --connector bitbrowser)").option("--no-poll", "Return immediately without polling").action(async (name, opts) => {
|
|
798
|
+
program2.command("runscript").argument("<name>", "Script name").description("Run a script (polls until complete)").option("--param <params...>", "Parameters as key=value").option("--connector <type>", "Browser connector: chrome, ziniao, or bitbrowser").option("--ziniao-profile <id>", "ZiNiao browser profile ID (with --connector ziniao)").option("--bitbrowser-profile <id>", "BitBrowser profile ID (with --connector bitbrowser)").option("--out <path>", "Where to write the script's exported file (default: ./<filename>)").option("--no-poll", "Return immediately without polling").action(async (name, opts) => {
|
|
791
799
|
try {
|
|
792
800
|
const params = {};
|
|
793
801
|
if (opts.param) {
|
|
@@ -796,6 +804,7 @@ function registerScriptCommands(program2) {
|
|
|
796
804
|
params[k] = rest.join("=");
|
|
797
805
|
}
|
|
798
806
|
}
|
|
807
|
+
if (opts.out) params.out_path = resolve(opts.out);
|
|
799
808
|
clearSessionId();
|
|
800
809
|
const task = await api.runScript(name, params, opts.connector, opts.ziniaoProfile, opts.bitbrowserProfile);
|
|
801
810
|
console.log(`Script started (task: ${task.id})`);
|
|
@@ -818,6 +827,18 @@ function registerScriptCommands(program2) {
|
|
|
818
827
|
saveSessionId(result.session_id);
|
|
819
828
|
}
|
|
820
829
|
console.log(formatScriptTask(result));
|
|
830
|
+
if (result.status === "completed") {
|
|
831
|
+
try {
|
|
832
|
+
const saved = await deliverArtifact(result, opts.out);
|
|
833
|
+
if (saved) console.log(`Saved -> ${saved}`);
|
|
834
|
+
} catch (err) {
|
|
835
|
+
const staged = result.output?.artifact_path;
|
|
836
|
+
console.error(`${formatError(err)}
|
|
837
|
+
Script completed; only saving the file failed.`);
|
|
838
|
+
if (staged) console.error(`The artifact is still at ${staged}.`);
|
|
839
|
+
process.exit(1);
|
|
840
|
+
}
|
|
841
|
+
}
|
|
821
842
|
} catch (err) {
|
|
822
843
|
console.error(formatError(err));
|
|
823
844
|
process.exit(1);
|
|
@@ -834,29 +855,7 @@ function registerScriptCommands(program2) {
|
|
|
834
855
|
});
|
|
835
856
|
}
|
|
836
857
|
function sleep(ms) {
|
|
837
|
-
return new Promise((
|
|
838
|
-
}
|
|
839
|
-
|
|
840
|
-
// src/commands/profile.ts
|
|
841
|
-
function registerProfileCommands(program2) {
|
|
842
|
-
program2.command("profiles").description("List browser profiles").action(async () => {
|
|
843
|
-
try {
|
|
844
|
-
const result = await api.listProfiles();
|
|
845
|
-
console.log(formatProfiles(result));
|
|
846
|
-
} catch (err) {
|
|
847
|
-
console.error(formatError(err));
|
|
848
|
-
process.exit(1);
|
|
849
|
-
}
|
|
850
|
-
});
|
|
851
|
-
program2.command("delete-profile").description("Delete a named browser profile").argument("<profile-id>", "Profile ID to delete").action(async (profileId) => {
|
|
852
|
-
try {
|
|
853
|
-
const result = await api.deleteProfile(profileId);
|
|
854
|
-
console.log(formatProfileDelete(result.profile_id));
|
|
855
|
-
} catch (err) {
|
|
856
|
-
console.error(formatError(err));
|
|
857
|
-
process.exit(1);
|
|
858
|
-
}
|
|
859
|
-
});
|
|
858
|
+
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
860
859
|
}
|
|
861
860
|
|
|
862
861
|
// src/ziniao-doctor.ts
|
|
@@ -1033,13 +1032,18 @@ function registerZiNiaoCommands(program2) {
|
|
|
1033
1032
|
}
|
|
1034
1033
|
|
|
1035
1034
|
// src/commands/recipes.ts
|
|
1036
|
-
import { writeFileSync as
|
|
1037
|
-
import { resolve } from "path";
|
|
1035
|
+
import { writeFileSync as writeFileSync4 } from "fs";
|
|
1036
|
+
import { resolve as resolve2 } from "path";
|
|
1038
1037
|
async function runExport(script, params, out, timeoutMs) {
|
|
1039
|
-
const outPath =
|
|
1038
|
+
const outPath = resolve2(out);
|
|
1040
1039
|
const result = await api.runRecipeScript(script, { ...params, out_path: outPath }, 2e3, timeoutMs);
|
|
1041
1040
|
if (!result.path) {
|
|
1042
|
-
|
|
1041
|
+
if (!result.artifact_path) {
|
|
1042
|
+
throw new Error(
|
|
1043
|
+
`Script ${script} finished but delivered no file \u2014 no workspace path and no staged artifact. Nothing was written to ${outPath}.`
|
|
1044
|
+
);
|
|
1045
|
+
}
|
|
1046
|
+
writeFileSync4(outPath, await api.fetchArtifact(result.artifact_path));
|
|
1043
1047
|
}
|
|
1044
1048
|
console.log(`Saved ${result.filename} -> ${outPath} (${result.size} bytes)`);
|
|
1045
1049
|
}
|
|
@@ -1111,7 +1115,6 @@ registerInteractionCommands(program);
|
|
|
1111
1115
|
registerInfoCommands(program);
|
|
1112
1116
|
registerTabCommands(program);
|
|
1113
1117
|
registerScriptCommands(program);
|
|
1114
|
-
registerProfileCommands(program);
|
|
1115
1118
|
registerZiNiaoCommands(program);
|
|
1116
1119
|
registerRecipeCommands(program);
|
|
1117
1120
|
registerBitBrowserCommands(program);
|