adspower-browser 1.0.2 → 2.0.0-beta.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.
@@ -23,6 +23,477 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
23
23
  mod
24
24
  ));
25
25
 
26
+ // src/index.ts
27
+ var import_commander = require("commander");
28
+
29
+ // src/store/index.ts
30
+ var Store = class {
31
+ apiKey;
32
+ baseUrl;
33
+ nodeEnv;
34
+ apiPort;
35
+ appPort;
36
+ intranet;
37
+ rpaPid;
38
+ rpaPlusPid;
39
+ aiPid;
40
+ status;
41
+ pid;
42
+ constructor() {
43
+ this.apiKey = "";
44
+ this.baseUrl = "";
45
+ this.nodeEnv = "";
46
+ this.apiPort = "";
47
+ this.appPort = "";
48
+ this.intranet = "";
49
+ this.rpaPid = "";
50
+ this.rpaPlusPid = "";
51
+ this.aiPid = "";
52
+ this.status = "stop";
53
+ this.pid = "";
54
+ }
55
+ getStoreValue(key) {
56
+ return this[key];
57
+ }
58
+ setStoreValue(key, value) {
59
+ this[key] = value;
60
+ }
61
+ clear() {
62
+ this.apiKey = "";
63
+ this.baseUrl = "";
64
+ this.nodeEnv = "";
65
+ this.apiPort = "";
66
+ this.appPort = "";
67
+ this.intranet = "";
68
+ this.rpaPid = "";
69
+ this.rpaPlusPid = "";
70
+ this.aiPid = "";
71
+ this.status = "stop";
72
+ this.pid = "";
73
+ }
74
+ getAllStoreValue() {
75
+ return {
76
+ apiKey: this.apiKey,
77
+ baseUrl: this.baseUrl,
78
+ nodeEnv: this.nodeEnv,
79
+ apiPort: this.apiPort,
80
+ appPort: this.appPort,
81
+ intranet: this.intranet,
82
+ rpaPid: this.rpaPid,
83
+ rpaPlusPid: this.rpaPlusPid,
84
+ aiPid: this.aiPid,
85
+ status: this.status,
86
+ pid: this.pid
87
+ };
88
+ }
89
+ };
90
+ var store = new Store();
91
+
92
+ // src/core/start.ts
93
+ var path2 = __toESM(require("path"));
94
+ var import_node_child_process2 = require("child_process");
95
+
96
+ // src/tools/index.ts
97
+ var os = __toESM(require("os"));
98
+ var path = __toESM(require("path"));
99
+ var fs = __toESM(require("fs"));
100
+ var crypto = __toESM(require("crypto"));
101
+ var util = __toESM(require("util"));
102
+ var import_node_child_process = require("child_process");
103
+ var import_colors = require("colors");
104
+ var import_fs_extra2 = require("fs-extra2");
105
+ var VERSION = "1.0.0";
106
+ var logError = (message) => {
107
+ console.error((0, import_colors.red)(message));
108
+ };
109
+ var logSuccess = (message) => {
110
+ console.log((0, import_colors.green)(message));
111
+ };
112
+ var logWarning = (message) => {
113
+ console.log((0, import_colors.yellow)(message));
114
+ };
115
+ var logInfo = (message) => {
116
+ console.log(message);
117
+ };
118
+ var sleepTime = (time) => new Promise((resolve) => {
119
+ setTimeout(() => {
120
+ resolve();
121
+ }, time);
122
+ });
123
+ var browsersKill = async () => {
124
+ await taskKillBrowser();
125
+ await taskKillFlowser();
126
+ };
127
+ var taskKillBrowser = () => new Promise((resolve) => {
128
+ const cmd = ["linux", "darwin"].includes(process.platform) ? 'pkill -u `whoami` -f "SunBrowser"' : "taskkill -PID SunBrowser.exe";
129
+ (0, import_node_child_process.exec)(cmd, (err) => {
130
+ if (err) {
131
+ }
132
+ resolve();
133
+ });
134
+ });
135
+ var taskKillFlowser = () => new Promise((resolve) => {
136
+ const cmd = ["linux", "darwin"].includes(process.platform) ? 'pkill -u `whoami` -f "FlowerBrowser"' : "taskkill -PID FlowerBrowser.exe";
137
+ (0, import_node_child_process.exec)(cmd, (err) => {
138
+ if (err) {
139
+ }
140
+ resolve();
141
+ });
142
+ });
143
+ var getHomedir = () => {
144
+ return (typeof os.homedir == "function" ? os.homedir() : process.env[process.platform == "win32" ? "USERPROFILE" : "HOME"]) || "~";
145
+ };
146
+ var getPidFileDir = () => {
147
+ const dir = path.join(getHomedir(), ".adspowerCli");
148
+ if (!fs.existsSync(dir)) {
149
+ (0, import_fs_extra2.ensureDirSync)(dir);
150
+ }
151
+ return dir;
152
+ };
153
+ var pidFileName = () => {
154
+ const md5 = crypto.createHash("md5").update(VERSION).digest("hex");
155
+ return md5;
156
+ };
157
+ var writePidFile = (config2) => {
158
+ const filePath = path.join(getPidFileDir(), pidFileName());
159
+ (0, import_fs_extra2.outputJsonSync)(filePath, config2 || {});
160
+ };
161
+ var readPidFile = () => {
162
+ const filePath = path.join(getPidFileDir(), pidFileName());
163
+ if (fs.existsSync(filePath)) {
164
+ return (0, import_fs_extra2.readJsonSync)(filePath);
165
+ }
166
+ return {};
167
+ };
168
+ var removePidFile = () => {
169
+ const filePath = path.join(getPidFileDir(), pidFileName());
170
+ if (fs.existsSync(filePath)) {
171
+ (0, import_fs_extra2.removeSync)(filePath);
172
+ }
173
+ };
174
+ var isRunning = (pid) => {
175
+ return new Promise((resolve) => {
176
+ if (pid) {
177
+ (0, import_node_child_process.exec)(
178
+ util.format(process.platform === "win32" ? 'tasklist /fi "PID eq %s" | findstr /i "node.exe"' : 'ps -f -p %s | grep "node"', pid),
179
+ function(err, stdout, stderr) {
180
+ resolve(!err && !!stdout.toString().trim());
181
+ }
182
+ );
183
+ } else {
184
+ resolve(false);
185
+ }
186
+ });
187
+ };
188
+ var ensureBrowserPath = () => {
189
+ const dir = path.join(__dirname, "../cwd/source", ".browser");
190
+ if (!fs.existsSync(dir)) {
191
+ (0, import_fs_extra2.ensureDirSync)(dir);
192
+ }
193
+ };
194
+ var getApiKeyAndPort = (options) => {
195
+ const apiKey = options.apiKey;
196
+ const port = options.port;
197
+ if (apiKey && port) {
198
+ return {
199
+ apiKey,
200
+ port
201
+ };
202
+ }
203
+ const result = {
204
+ apiKey,
205
+ port
206
+ };
207
+ const processInstance = readPidFile();
208
+ if (!apiKey && processInstance.apiKey) {
209
+ result.apiKey = processInstance.apiKey;
210
+ }
211
+ if (!port && processInstance.apiPort) {
212
+ result.port = processInstance.apiPort;
213
+ }
214
+ return result;
215
+ };
216
+ var hasRunning = async (options) => {
217
+ const { apiKey, port } = options;
218
+ if (apiKey && port) {
219
+ return true;
220
+ }
221
+ const processInstance = readPidFile();
222
+ if (processInstance.pid) {
223
+ return await isRunning(processInstance.pid);
224
+ }
225
+ return false;
226
+ };
227
+ var loadingFramesList = {
228
+ default: ["|", "/", "-", "\\"],
229
+ frames: ["\u2596", "\u2597", "\u2598", "\u2599", "\u259A", "\u259B", "\u259C", "\u259D", "\u259E", "\u259F"],
230
+ dotFrames: ["\u2840", "\u2844", "\u2846", "\u2847", "\u284F", "\u285F", "\u287F", "\u28FF", "\u28F7", "\u28F6", "\u28E6", "\u28E4", "\u28E0", "\u2880"]
231
+ };
232
+ var createLoading = (text) => {
233
+ if (!process.stdout.isTTY) {
234
+ return {
235
+ stop() {
236
+ }
237
+ };
238
+ }
239
+ let index = 0;
240
+ const frames = loadingFramesList.default;
241
+ process.stdout.write(`${frames[index]} ${text}`);
242
+ const timer = setInterval(() => {
243
+ index = (index + 1) % frames.length;
244
+ process.stdout.write(`\r${frames[index]} ${text}`);
245
+ }, 120);
246
+ return {
247
+ stop() {
248
+ clearInterval(timer);
249
+ process.stdout.write(`\r${" ".repeat(text.length + 2)}\r`);
250
+ }
251
+ };
252
+ };
253
+ var initSqlite3 = () => {
254
+ const sqliteFile = path.join(__dirname, "../cwd/lib", "node_sqlite3.node");
255
+ if (fs.existsSync(sqliteFile)) {
256
+ return;
257
+ }
258
+ const isMac = process.platform === "darwin";
259
+ const isLinux = process.platform === "linux";
260
+ const is32 = process.arch === "ia32";
261
+ const isArm = process.arch === "arm64";
262
+ const isX64 = process.arch === "x64";
263
+ const macFolder = isArm ? "arm64" : "mac";
264
+ const winFolder = is32 ? "ia32" : "x64";
265
+ const linuxFolder = isLinux && isX64 && "linux";
266
+ const sqliteFolder = isMac ? macFolder : isLinux ? linuxFolder : winFolder;
267
+ const dir = path.join(__dirname, `../sqlite/${sqliteFolder}`);
268
+ if (!fs.existsSync(dir)) {
269
+ throw new Error(`SQLite folder not found: ${dir}`);
270
+ } else {
271
+ const sqliteFile2 = path.join(dir, "node_sqlite3.node");
272
+ const cwdPath = path.join(__dirname, "../cwd/lib");
273
+ (0, import_fs_extra2.copySync)(sqliteFile2, path.join(cwdPath, "node_sqlite3.node"));
274
+ logSuccess(`[i] SQLite file initialized successfully!`);
275
+ }
276
+ };
277
+
278
+ // src/core/start.ts
279
+ var getEnv = () => {
280
+ const env = {
281
+ ...process.env,
282
+ // 系统的环境变量信息
283
+ API_KEY: store.getStoreValue("apiKey"),
284
+ IS_CLOUD_BROWSER: true
285
+ // 云浏览器场景预留标识
286
+ };
287
+ if (store.getStoreValue("baseUrl")) {
288
+ env.BASE_URL = store.getStoreValue("baseUrl");
289
+ }
290
+ if (store.getStoreValue("nodeEnv")) {
291
+ env.NODE_ENV = store.getStoreValue("nodeEnv");
292
+ }
293
+ return env;
294
+ };
295
+ var startChild = (type) => {
296
+ let timer;
297
+ let child = null;
298
+ return new Promise(async (resolve, reject) => {
299
+ initSqlite3();
300
+ const processInstance = readPidFile();
301
+ if (processInstance && processInstance.pid) {
302
+ const isRun = await isRunning(processInstance.pid);
303
+ removePidFile();
304
+ if (isRun) {
305
+ process.kill(Number(processInstance.pid), "SIGKILL");
306
+ await sleepTime(1e3);
307
+ }
308
+ }
309
+ const env = Object.fromEntries(
310
+ Object.entries(getEnv()).map(([key, value]) => [key, value == null ? value : String(value)])
311
+ );
312
+ try {
313
+ const mainJs = path2.join(__dirname, "../cwd/lib", "main.min.js");
314
+ child = (0, import_node_child_process2.fork)(mainJs, {
315
+ env,
316
+ detached: true,
317
+ stdio: ["ignore", "ignore", "ignore", "ipc"]
318
+ });
319
+ ensureBrowserPath();
320
+ store.setStoreValue("status", "starting");
321
+ logSuccess(`[i] Adspower program is starting...`);
322
+ store.setStoreValue("pid", child?.pid?.toString() || "");
323
+ let isAppPortOk = false;
324
+ writePidFile(store.getAllStoreValue());
325
+ child.on("message", async (msg) => {
326
+ const text = String(msg);
327
+ if (text.indexOf("SERVER_PORT_$$_") === 0 && !isAppPortOk) {
328
+ const port = text.replace("SERVER_PORT_$$_", "").trim();
329
+ store.setStoreValue("appPort", port);
330
+ isAppPortOk = true;
331
+ }
332
+ if (text.indexOf("START_API_SERVER_SUCCESS_$$_") === 0) {
333
+ const port = text.replace("START_API_SERVER_SUCCESS_$$_", "").trim();
334
+ store.setStoreValue("apiPort", port);
335
+ logSuccess(`Server running at:`);
336
+ logSuccess(` - local: http://local.adspower.net:${port}`);
337
+ writePidFile(store.getAllStoreValue());
338
+ if (child) {
339
+ child.disconnect();
340
+ child.unref();
341
+ }
342
+ }
343
+ if (text.indexOf("START_API_SERVER_FAIL_$$_") === 0) {
344
+ const serverMsg = text.replace("START_API_SERVER_FAIL_$$_", "").split("_").filter(Boolean);
345
+ if (serverMsg[0]) {
346
+ logError(`ERROR - ${serverMsg[0]}`);
347
+ }
348
+ if (serverMsg[1]) {
349
+ logError(`ERROR - ${serverMsg[1]}`);
350
+ }
351
+ process.exit(0);
352
+ }
353
+ if (text === "start") {
354
+ clearTimeout(timer);
355
+ resolve();
356
+ store.setStoreValue("status", "doing");
357
+ writePidFile(store.getAllStoreValue());
358
+ }
359
+ if (text === "restart") {
360
+ child && child.kill("SIGKILL");
361
+ store.setStoreValue("status", "restarting");
362
+ startChild("2").catch(() => {
363
+ });
364
+ }
365
+ if (text.indexOf("INTRANET_$$_") > -1) {
366
+ const arr = text.split("_$$_");
367
+ if (arr && arr[1]) {
368
+ store.setStoreValue("intranet", arr[1]);
369
+ }
370
+ }
371
+ if (text === "browser-kill") {
372
+ await browsersKill();
373
+ }
374
+ if (text.indexOf("RPA_PROCESS_PID_") > -1) {
375
+ const rpaPid = text.replace("RPA_PROCESS_PID_", "");
376
+ store.setStoreValue("rpaPid", rpaPid);
377
+ }
378
+ if (text.indexOf("RPA_PLUS_PROCESS_PID_") > -1) {
379
+ const rpaPlusPid = text.replace("RPA_PLUS_PROCESS_PID_", "");
380
+ store.setStoreValue("rpaPlusPid", rpaPlusPid);
381
+ }
382
+ if (text.indexOf("AI_PROCESS_PID_") > -1) {
383
+ const aiPid = text.replace("AI_PROCESS_PID_", "");
384
+ store.setStoreValue("aiPid", aiPid);
385
+ }
386
+ });
387
+ child.on("error", (err) => {
388
+ logError(`[!] Node\u542F\u52A8\u5931\u8D25: ${err.message}`);
389
+ store.setStoreValue("status", "stop");
390
+ store.clear();
391
+ removePidFile();
392
+ process.exit(0);
393
+ });
394
+ child.on("exit", async (code, signal) => {
395
+ if (signal === "SIGKILL") {
396
+ await browsersKill();
397
+ store.clear();
398
+ removePidFile();
399
+ } else {
400
+ child = null;
401
+ await sleepTime(500);
402
+ startChild("2").then(() => {
403
+ }).catch(() => {
404
+ logError("[!] Restart failed");
405
+ });
406
+ }
407
+ });
408
+ timer = setTimeout(() => {
409
+ child && child.kill("SIGKILL");
410
+ child = null;
411
+ store.setStoreValue("status", "stop");
412
+ logError("[!] Start Timeout");
413
+ reject("Start Timeout");
414
+ }, 30 * 1e3);
415
+ } catch (error) {
416
+ clearTimeout(timer);
417
+ reject(error);
418
+ child = null;
419
+ store.clear();
420
+ logError(`[!] Node\u542F\u52A8\u5931\u8D25: ${error instanceof Error ? error.message : JSON.stringify(error)}`);
421
+ }
422
+ });
423
+ };
424
+ var stopChild = async () => {
425
+ const processInstance = readPidFile();
426
+ if (processInstance.pid) {
427
+ const isRun = await isRunning(processInstance.pid);
428
+ try {
429
+ process.kill(Number(processInstance.pid), "SIGKILL");
430
+ removePidFile();
431
+ } catch (error) {
432
+ try {
433
+ await sleepTime(2e3);
434
+ process.kill(Number(processInstance.pid), "SIGKILL");
435
+ removePidFile();
436
+ } catch (error2) {
437
+ logError(`[!] Stop child fail: ${error2 instanceof Error ? error2.message : JSON.stringify(error2)}`);
438
+ if (isRun) {
439
+ logWarning(`[!] Please manually close the browser process: ${processInstance.pid}`);
440
+ }
441
+ return;
442
+ }
443
+ }
444
+ logSuccess("[i] Adspower program is stopped");
445
+ } else {
446
+ logInfo("[i] No running adspower program");
447
+ }
448
+ };
449
+ var restartChild = async () => {
450
+ const processInstance = readPidFile();
451
+ if (processInstance.pid) {
452
+ const apiKey = processInstance.apiKey;
453
+ const baseUrl = processInstance.baseUrl;
454
+ const nodeEnv = processInstance.nodeEnv;
455
+ await stopChild();
456
+ await sleepTime(1e3);
457
+ store.setStoreValue("apiKey", apiKey);
458
+ store.setStoreValue("baseUrl", baseUrl);
459
+ store.setStoreValue("nodeEnv", nodeEnv);
460
+ await startChild().then(() => {
461
+ logSuccess("[i] Adspower program is restarted");
462
+ }).catch((error) => {
463
+ logError(`[!] Restart failed: ${error.message}`);
464
+ });
465
+ } else {
466
+ logInfo("[i] No running adspower program");
467
+ }
468
+ };
469
+ var getChildStatus = async () => {
470
+ const processInstance = readPidFile();
471
+ if (processInstance.pid) {
472
+ const isRun = await isRunning(processInstance.pid);
473
+ if (!isRun) {
474
+ removePidFile();
475
+ logInfo("[i] Adspower program is not running");
476
+ return;
477
+ }
478
+ const status = processInstance.status;
479
+ if (status === "starting") {
480
+ logSuccess("[i] Adspower program is starting...");
481
+ } else if (status === "doing" && processInstance.apiPort) {
482
+ logSuccess("[i] Adspower program is running at:");
483
+ logSuccess(` - http://local.adspower.net:${processInstance.apiPort}`);
484
+ } else if (status === "stop") {
485
+ logInfo("[i] Adspower program is stopped");
486
+ } else {
487
+ logInfo("[i] Adspower program is not started");
488
+ }
489
+ } else {
490
+ logInfo("[i] Adspower program is not running");
491
+ }
492
+ };
493
+
494
+ // src/index.ts
495
+ var import_colors2 = require("colors");
496
+
26
497
  // ../core/src/constants/api.ts
27
498
  var import_axios = __toESM(require("axios"));
28
499
 
@@ -40,16 +511,28 @@ function parseArgs() {
40
511
  }
41
512
  }
42
513
  return {
43
- port: port || process.env.PORT || "50325",
514
+ port: port || process.env.PORT || "50326",
44
515
  apiKey: apiKey || process.env.API_KEY
45
516
  };
46
517
  }
47
518
  var config = parseArgs();
519
+ var updateConfig = (apiKey, port) => {
520
+ if (apiKey) {
521
+ config.apiKey = apiKey;
522
+ }
523
+ if (port) {
524
+ config.port = port;
525
+ }
526
+ };
48
527
  var PORT = config.port;
49
528
  var API_KEY = config.apiKey;
529
+ var CONFIG = config;
50
530
 
51
531
  // ../core/src/constants/api.ts
52
532
  var LOCAL_API_BASE = `http://127.0.0.1:${PORT}`;
533
+ var getLocalApiBase = () => {
534
+ return `http://127.0.0.1:${CONFIG.port}`;
535
+ };
53
536
  var API_ENDPOINTS = {
54
537
  STATUS: "/status",
55
538
  START_BROWSER: "/api/v2/browser-profile/start",
@@ -87,6 +570,11 @@ var API_ENDPOINTS = {
87
570
  var apiClient = import_axios.default.create({
88
571
  headers: API_KEY ? { "Authorization": `Bearer ${API_KEY}` } : {}
89
572
  });
573
+ var getApiClient = () => {
574
+ return import_axios.default.create({
575
+ headers: CONFIG.apiKey ? { "Authorization": `Bearer ${CONFIG.apiKey}` } : {}
576
+ });
577
+ };
90
578
 
91
579
  // ../core/src/utils/requestBuilder.ts
92
580
  function buildRequestBody(params) {
@@ -174,7 +662,7 @@ var browserHandlers = {
174
662
  if (cdpMask) {
175
663
  requestBody.cdp_mask = cdpMask;
176
664
  }
177
- const response = await apiClient.post(`${LOCAL_API_BASE}${API_ENDPOINTS.START_BROWSER}`, requestBody);
665
+ const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.START_BROWSER}`, requestBody);
178
666
  if (response.data.code === 0) {
179
667
  return `Browser opened successfully with: ${Object.entries(response.data.data).map(([key, value]) => {
180
668
  if (value && typeof value === "object") {
@@ -193,7 +681,7 @@ var browserHandlers = {
193
681
  if (profileNo) {
194
682
  requestBody.profile_no = profileNo;
195
683
  }
196
- const response = await apiClient.post(`${LOCAL_API_BASE}${API_ENDPOINTS.CLOSE_BROWSER}`, requestBody);
684
+ const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.CLOSE_BROWSER}`, requestBody);
197
685
  if (response.data.code === 0) {
198
686
  return "Browser closed successfully";
199
687
  }
@@ -201,7 +689,7 @@ var browserHandlers = {
201
689
  },
202
690
  async createBrowser(params) {
203
691
  const requestBody = buildRequestBody(params);
204
- const response = await apiClient.post(`${LOCAL_API_BASE}${API_ENDPOINTS.CREATE_BROWSER}`, requestBody);
692
+ const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.CREATE_BROWSER}`, requestBody);
205
693
  if (response.data.code === 0) {
206
694
  return `Browser created successfully with: ${Object.entries(response.data.data).map(([key, value]) => `${key}: ${value}`).join("\n")}`;
207
695
  }
@@ -209,14 +697,14 @@ var browserHandlers = {
209
697
  },
210
698
  async updateBrowser(params) {
211
699
  const requestBody = buildRequestBody(params);
212
- const response = await apiClient.post(`${LOCAL_API_BASE}${API_ENDPOINTS.UPDATE_BROWSER}`, requestBody);
700
+ const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.UPDATE_BROWSER}`, requestBody);
213
701
  if (response.data.code === 0) {
214
702
  return `Browser updated successfully with: ${Object.entries(response.data.data || {}).map(([key, value]) => `${key}: ${value}`).join("\n")}`;
215
703
  }
216
704
  throw new Error(`Failed to update browser: ${response.data.msg}`);
217
705
  },
218
706
  async deleteBrowser({ profileIds }) {
219
- const response = await apiClient.post(`${LOCAL_API_BASE}${API_ENDPOINTS.DELETE_BROWSER}`, {
707
+ const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.DELETE_BROWSER}`, {
220
708
  profile_id: profileIds
221
709
  });
222
710
  if (response.data.code === 0) {
@@ -260,21 +748,21 @@ var browserHandlers = {
260
748
  if (name_filter) {
261
749
  requestBody.name_filter = name_filter;
262
750
  }
263
- const response = await apiClient.post(`${LOCAL_API_BASE}${API_ENDPOINTS.GET_BROWSER_LIST}`, requestBody);
751
+ const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.GET_BROWSER_LIST}`, requestBody);
264
752
  if (response.data.code === 0) {
265
753
  return `Browser list: ${JSON.stringify(response.data.data.list, null, 2)}`;
266
754
  }
267
755
  throw new Error(`Failed to get browser list: ${response.data.msg}`);
268
756
  },
269
757
  async getOpenedBrowser() {
270
- const response = await apiClient.get(`${LOCAL_API_BASE}${API_ENDPOINTS.GET_OPENED_BROWSER}`);
758
+ const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.GET_OPENED_BROWSER}`);
271
759
  if (response.data.code === 0) {
272
760
  return `Opened browser list: ${JSON.stringify(response.data.data.list, null, 2)}`;
273
761
  }
274
762
  throw new Error(`Failed to get opened browsers: ${response.data.msg}`);
275
763
  },
276
764
  async moveBrowser({ groupId, userIds }) {
277
- const response = await apiClient.post(`${LOCAL_API_BASE}${API_ENDPOINTS.MOVE_BROWSER}`, {
765
+ const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.MOVE_BROWSER}`, {
278
766
  group_id: groupId,
279
767
  user_ids: userIds
280
768
  });
@@ -291,7 +779,7 @@ var browserHandlers = {
291
779
  if (profileNo) {
292
780
  params.set("profile_no", profileNo);
293
781
  }
294
- const response = await apiClient.get(`${LOCAL_API_BASE}${API_ENDPOINTS.GET_PROFILE_COOKIES}`, { params });
782
+ const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.GET_PROFILE_COOKIES}`, { params });
295
783
  if (response.data.code === 0) {
296
784
  return `Profile cookies: ${JSON.stringify(response.data.data, null, 2)}`;
297
785
  }
@@ -305,14 +793,14 @@ var browserHandlers = {
305
793
  if (profileNo && profileNo.length > 0) {
306
794
  requestBody.profile_no = profileNo;
307
795
  }
308
- const response = await apiClient.post(`${LOCAL_API_BASE}${API_ENDPOINTS.GET_PROFILE_UA}`, requestBody);
796
+ const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.GET_PROFILE_UA}`, requestBody);
309
797
  if (response.data.code === 0) {
310
798
  return `Profile User-Agent: ${JSON.stringify(response.data.data, null, 2)}`;
311
799
  }
312
800
  throw new Error(`Failed to get profile User-Agent: ${response.data.msg}`);
313
801
  },
314
802
  async closeAllProfiles(_params) {
315
- const response = await apiClient.post(`${LOCAL_API_BASE}${API_ENDPOINTS.CLOSE_ALL_PROFILES}`, {});
803
+ const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.CLOSE_ALL_PROFILES}`, {});
316
804
  if (response.data.code === 0) {
317
805
  return "All profiles closed successfully";
318
806
  }
@@ -326,14 +814,14 @@ var browserHandlers = {
326
814
  if (profileNo && profileNo.length > 0) {
327
815
  requestBody.profile_no = profileNo;
328
816
  }
329
- const response = await apiClient.post(`${LOCAL_API_BASE}${API_ENDPOINTS.NEW_FINGERPRINT}`, requestBody);
817
+ const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.NEW_FINGERPRINT}`, requestBody);
330
818
  if (response.data.code === 0) {
331
819
  return `New fingerprint created: ${JSON.stringify(response.data.data, null, 2)}`;
332
820
  }
333
821
  throw new Error(`Failed to create new fingerprint: ${response.data.msg}`);
334
822
  },
335
823
  async deleteCacheV2({ profileIds, type }) {
336
- const response = await apiClient.post(`${LOCAL_API_BASE}${API_ENDPOINTS.DELETE_CACHE_V2}`, {
824
+ const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.DELETE_CACHE_V2}`, {
337
825
  profile_id: profileIds,
338
826
  type
339
827
  });
@@ -353,7 +841,7 @@ var browserHandlers = {
353
841
  if (content !== void 0) {
354
842
  requestBody.content = content;
355
843
  }
356
- const response = await apiClient.post(`${LOCAL_API_BASE}${API_ENDPOINTS.SHARE_PROFILE}`, requestBody);
844
+ const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.SHARE_PROFILE}`, requestBody);
357
845
  if (response.data.code === 0) {
358
846
  return `Profiles shared successfully: ${profileIds.join(", ")}`;
359
847
  }
@@ -367,14 +855,14 @@ var browserHandlers = {
367
855
  if (profileNo) {
368
856
  params.set("profile_no", profileNo);
369
857
  }
370
- const response = await apiClient.get(`${LOCAL_API_BASE}${API_ENDPOINTS.GET_BROWSER_ACTIVE}`, { params });
858
+ const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.GET_BROWSER_ACTIVE}`, { params });
371
859
  if (response.data.code === 0) {
372
860
  return `Browser active info: ${JSON.stringify(response.data.data, null, 2)}`;
373
861
  }
374
862
  throw new Error(`Failed to get browser active: ${response.data.msg}`);
375
863
  },
376
864
  async getCloudActive({ userIds }) {
377
- const response = await apiClient.post(`${LOCAL_API_BASE}${API_ENDPOINTS.GET_CLOUD_ACTIVE}`, {
865
+ const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.GET_CLOUD_ACTIVE}`, {
378
866
  user_ids: userIds
379
867
  });
380
868
  if (response.data.code === 0) {
@@ -393,7 +881,7 @@ var groupHandlers = {
393
881
  if (remark !== void 0) {
394
882
  requestBody.remark = remark;
395
883
  }
396
- const response = await apiClient.post(`${LOCAL_API_BASE}${API_ENDPOINTS.CREATE_GROUP}`, requestBody);
884
+ const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.CREATE_GROUP}`, requestBody);
397
885
  if (response.data.code === 0) {
398
886
  return `Group created successfully with name: ${groupName}${remark ? `, remark: ${remark}` : ""}`;
399
887
  }
@@ -407,7 +895,7 @@ var groupHandlers = {
407
895
  if (remark !== void 0) {
408
896
  requestBody.remark = remark;
409
897
  }
410
- const response = await apiClient.post(`${LOCAL_API_BASE}${API_ENDPOINTS.UPDATE_GROUP}`, requestBody);
898
+ const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.UPDATE_GROUP}`, requestBody);
411
899
  if (response.data.code === 0) {
412
900
  return `Group updated successfully with id: ${groupId}, name: ${groupName}${remark !== void 0 ? `, remark: ${remark === null ? "(cleared)" : remark}` : ""}`;
413
901
  }
@@ -424,7 +912,7 @@ var groupHandlers = {
424
912
  if (page) {
425
913
  params.set("page", page.toString());
426
914
  }
427
- const response = await apiClient.get(`${LOCAL_API_BASE}${API_ENDPOINTS.GET_GROUP_LIST}`, { params });
915
+ const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.GET_GROUP_LIST}`, { params });
428
916
  return `Group list: ${JSON.stringify(response.data.data.list, null, 2)}`;
429
917
  }
430
918
  };
@@ -432,7 +920,7 @@ var groupHandlers = {
432
920
  // ../core/src/handlers/application.ts
433
921
  var applicationHandlers = {
434
922
  async checkStatus() {
435
- const response = await apiClient.get(`${LOCAL_API_BASE}${API_ENDPOINTS.STATUS}`);
923
+ const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.STATUS}`);
436
924
  return `Connection status: ${JSON.stringify(response.data, null, 2)}`;
437
925
  },
438
926
  async getApplicationList({ category_id, page, limit }) {
@@ -446,7 +934,7 @@ var applicationHandlers = {
446
934
  if (limit !== void 0) {
447
935
  params.set("limit", limit.toString());
448
936
  }
449
- const response = await apiClient.get(`${LOCAL_API_BASE}${API_ENDPOINTS.GET_APPLICATION_LIST}`, { params });
937
+ const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.GET_APPLICATION_LIST}`, { params });
450
938
  return `Application list: ${JSON.stringify(response.data.data.list, null, 2)}`;
451
939
  }
452
940
  };
@@ -508,7 +996,7 @@ function buildCreateProxyRequestBody(proxy) {
508
996
  var proxyHandlers = {
509
997
  async createProxy(params) {
510
998
  const requestBody = params.proxies.map((proxy) => buildCreateProxyRequestBody(proxy));
511
- const response = await apiClient.post(`${LOCAL_API_BASE}${API_ENDPOINTS.CREATE_PROXY}`, requestBody);
999
+ const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.CREATE_PROXY}`, requestBody);
512
1000
  if (response.data.code === 0) {
513
1001
  return `Proxy created successfully with: ${Object.entries(response.data.data || {}).map(([key, value]) => `${key}: ${value}`).join("\n")}`;
514
1002
  }
@@ -516,7 +1004,7 @@ var proxyHandlers = {
516
1004
  },
517
1005
  async updateProxy(params) {
518
1006
  const requestBody = buildProxyRequestBody(params);
519
- const response = await apiClient.post(`${LOCAL_API_BASE}${API_ENDPOINTS.UPDATE_PROXY}`, requestBody);
1007
+ const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.UPDATE_PROXY}`, requestBody);
520
1008
  if (response.data.code === 0) {
521
1009
  return `Proxy updated successfully with: ${Object.entries(response.data.data || {}).map(([key, value]) => `${key}: ${value}`).join("\n")}`;
522
1010
  }
@@ -534,14 +1022,14 @@ var proxyHandlers = {
534
1022
  if (proxyId && proxyId.length > 0) {
535
1023
  requestBody.proxy_id = proxyId;
536
1024
  }
537
- const response = await apiClient.post(`${LOCAL_API_BASE}${API_ENDPOINTS.GET_PROXY_LIST}`, requestBody);
1025
+ const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.GET_PROXY_LIST}`, requestBody);
538
1026
  if (response.data.code === 0) {
539
1027
  return `Proxy list: ${JSON.stringify(response.data.data.list || response.data.data, null, 2)}`;
540
1028
  }
541
1029
  throw new Error(`Failed to get proxy list: ${response.data.msg}`);
542
1030
  },
543
1031
  async deleteProxy({ proxyIds }) {
544
- const response = await apiClient.post(`${LOCAL_API_BASE}${API_ENDPOINTS.DELETE_PROXY}`, {
1032
+ const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.DELETE_PROXY}`, {
545
1033
  proxy_id: proxyIds
546
1034
  });
547
1035
  if (response.data.code === 0) {
@@ -565,28 +1053,28 @@ var tagHandlers = {
565
1053
  if (page !== void 0) {
566
1054
  requestBody.page = page;
567
1055
  }
568
- const response = await apiClient.post(`${LOCAL_API_BASE}${API_ENDPOINTS.GET_TAG_LIST}`, requestBody);
1056
+ const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.GET_TAG_LIST}`, requestBody);
569
1057
  if (response.data.code === 0) {
570
1058
  return `Tag list: ${JSON.stringify(response.data.data.list || response.data.data, null, 2)}`;
571
1059
  }
572
1060
  throw new Error(`Failed to get tag list: ${response.data.msg}`);
573
1061
  },
574
1062
  async createTag({ tags }) {
575
- const response = await apiClient.post(`${LOCAL_API_BASE}${API_ENDPOINTS.CREATE_TAG}`, { tags });
1063
+ const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.CREATE_TAG}`, { tags });
576
1064
  if (response.data.code === 0) {
577
1065
  return `Tags created successfully: ${JSON.stringify(response.data.data, null, 2)}`;
578
1066
  }
579
1067
  throw new Error(`Failed to create tags: ${response.data.msg}`);
580
1068
  },
581
1069
  async updateTag({ tags }) {
582
- const response = await apiClient.post(`${LOCAL_API_BASE}${API_ENDPOINTS.UPDATE_TAG}`, { tags });
1070
+ const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.UPDATE_TAG}`, { tags });
583
1071
  if (response.data.code === 0) {
584
1072
  return `Tags updated successfully: ${JSON.stringify(response.data.data, null, 2)}`;
585
1073
  }
586
1074
  throw new Error(`Failed to update tags: ${response.data.msg}`);
587
1075
  },
588
1076
  async deleteTag({ ids }) {
589
- const response = await apiClient.post(`${LOCAL_API_BASE}${API_ENDPOINTS.DELETE_TAG}`, { ids });
1077
+ const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.DELETE_TAG}`, { ids });
590
1078
  if (response.data.code === 0) {
591
1079
  return `Tags deleted successfully: ${ids.join(", ")}`;
592
1080
  }
@@ -654,7 +1142,7 @@ var defaultDownloadsPath = import_path.default.join(import_os.default.homedir(),
654
1142
  // ../core/src/handlers/kernel.ts
655
1143
  var kernelHandlers = {
656
1144
  async downloadKernel({ kernel_type, kernel_version }) {
657
- const response = await apiClient.post(`${LOCAL_API_BASE}${API_ENDPOINTS.DOWNLOAD_KERNEL}`, {
1145
+ const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.DOWNLOAD_KERNEL}`, {
658
1146
  kernel_type,
659
1147
  kernel_version
660
1148
  });
@@ -668,7 +1156,7 @@ var kernelHandlers = {
668
1156
  if (kernel_type) {
669
1157
  params.set("kernel_type", kernel_type);
670
1158
  }
671
- const response = await apiClient.get(`${LOCAL_API_BASE}${API_ENDPOINTS.GET_KERNEL_LIST}`, { params });
1159
+ const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.GET_KERNEL_LIST}`, { params });
672
1160
  if (response.data.code === 0) {
673
1161
  return `Kernel list: ${JSON.stringify(response.data.data.list || response.data.data, null, 2)}`;
674
1162
  }
@@ -683,7 +1171,7 @@ var patchHandlers = {
683
1171
  if (version_type) {
684
1172
  requestBody.version_type = version_type;
685
1173
  }
686
- const response = await apiClient.post(`${LOCAL_API_BASE}${API_ENDPOINTS.UPDATE_PATCH}`, requestBody);
1174
+ const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.UPDATE_PATCH}`, requestBody);
687
1175
  if (response.data.code === 0) {
688
1176
  return `Patch update status: ${JSON.stringify(response.data.data, null, 2)}, message: ${response.data.msg}`;
689
1177
  }
@@ -1420,38 +1908,134 @@ var schemas = {
1420
1908
 
1421
1909
  // src/cli.ts
1422
1910
  var STATELESS_HANDLERS = {
1423
- "open-browser": browserHandlers.openBrowser,
1424
- "close-browser": browserHandlers.closeBrowser,
1425
- "create-browser": browserHandlers.createBrowser,
1426
- "update-browser": browserHandlers.updateBrowser,
1427
- "delete-browser": browserHandlers.deleteBrowser,
1428
- "get-browser-list": browserHandlers.getBrowserList,
1429
- "get-opened-browser": browserHandlers.getOpenedBrowser,
1430
- "move-browser": browserHandlers.moveBrowser,
1431
- "get-profile-cookies": browserHandlers.getProfileCookies,
1432
- "get-profile-ua": browserHandlers.getProfileUa,
1433
- "close-all-profiles": browserHandlers.closeAllProfiles,
1434
- "new-fingerprint": browserHandlers.newFingerprint,
1435
- "delete-cache-v2": browserHandlers.deleteCacheV2,
1436
- "share-profile": browserHandlers.shareProfile,
1437
- "get-browser-active": browserHandlers.getBrowserActive,
1438
- "get-cloud-active": browserHandlers.getCloudActive,
1439
- "create-group": groupHandlers.createGroup,
1440
- "update-group": groupHandlers.updateGroup,
1441
- "get-group-list": groupHandlers.getGroupList,
1442
- "check-status": applicationHandlers.checkStatus,
1443
- "get-application-list": applicationHandlers.getApplicationList,
1444
- "create-proxy": proxyHandlers.createProxy,
1445
- "update-proxy": proxyHandlers.updateProxy,
1446
- "get-proxy-list": proxyHandlers.getProxyList,
1447
- "delete-proxy": proxyHandlers.deleteProxy,
1448
- "get-tag-list": tagHandlers.getTagList,
1449
- "create-tag": tagHandlers.createTag,
1450
- "update-tag": tagHandlers.updateTag,
1451
- "delete-tag": tagHandlers.deleteTag,
1452
- "download-kernel": kernelHandlers.downloadKernel,
1453
- "get-kernel-list": kernelHandlers.getKernelList,
1454
- "update-patch": patchHandlers.updatePatch
1911
+ "open-browser": {
1912
+ fn: browserHandlers.openBrowser,
1913
+ description: "Open the browser, both environment and profile mean browser"
1914
+ },
1915
+ "close-browser": {
1916
+ fn: browserHandlers.closeBrowser,
1917
+ description: "Close the browser"
1918
+ },
1919
+ "create-browser": {
1920
+ fn: browserHandlers.createBrowser,
1921
+ description: "Create a browser"
1922
+ },
1923
+ "update-browser": {
1924
+ fn: browserHandlers.updateBrowser,
1925
+ description: "Update the browser"
1926
+ },
1927
+ "delete-browser": {
1928
+ fn: browserHandlers.deleteBrowser,
1929
+ description: "Delete the browser"
1930
+ },
1931
+ "get-browser-list": {
1932
+ fn: browserHandlers.getBrowserList,
1933
+ description: "Get the list of browsers"
1934
+ },
1935
+ "get-opened-browser": {
1936
+ fn: browserHandlers.getOpenedBrowser,
1937
+ description: "Get the list of opened browsers"
1938
+ },
1939
+ "move-browser": {
1940
+ fn: browserHandlers.moveBrowser,
1941
+ description: "Move browsers to a group"
1942
+ },
1943
+ "get-profile-cookies": {
1944
+ fn: browserHandlers.getProfileCookies,
1945
+ description: "Query and return cookies of the specified profile. Only one profile can be queried per request."
1946
+ },
1947
+ "get-profile-ua": {
1948
+ fn: browserHandlers.getProfileUa,
1949
+ description: "Query and return the User-Agent of specified profiles. Up to 10 profiles can be queried per request."
1950
+ },
1951
+ "close-all-profiles": {
1952
+ fn: browserHandlers.closeAllProfiles,
1953
+ description: "Close all opened profiles on the current device"
1954
+ },
1955
+ "new-fingerprint": {
1956
+ fn: browserHandlers.newFingerprint,
1957
+ description: "Generate a new fingerprint for specified profiles. Up to 10 profiles are supported per request."
1958
+ },
1959
+ "delete-cache-v2": {
1960
+ fn: browserHandlers.deleteCacheV2,
1961
+ description: "Clear local cache of specific profiles.For account security, please ensure that there are no open browsers on the device when using this interface."
1962
+ },
1963
+ "share-profile": {
1964
+ fn: browserHandlers.shareProfile,
1965
+ description: "Share profiles via account email or phone number. The maximum number of profiles that can be shared at one time is 200."
1966
+ },
1967
+ "get-browser-active": {
1968
+ fn: browserHandlers.getBrowserActive,
1969
+ description: "Get active browser profile information"
1970
+ },
1971
+ "get-cloud-active": {
1972
+ fn: browserHandlers.getCloudActive,
1973
+ description: 'Query the status of browser profiles by user_id, up to 100 profiles per request. If the team has enabled "Multi device mode," specific statuses cannot be retrieved and the response will indicate "Profile not opened."'
1974
+ },
1975
+ "create-group": {
1976
+ fn: groupHandlers.createGroup,
1977
+ description: "Create a browser group"
1978
+ },
1979
+ "update-group": {
1980
+ fn: groupHandlers.updateGroup,
1981
+ description: "Update the browser group"
1982
+ },
1983
+ "get-group-list": {
1984
+ fn: groupHandlers.getGroupList,
1985
+ description: "Get the list of groups"
1986
+ },
1987
+ "check-status": {
1988
+ fn: applicationHandlers.checkStatus,
1989
+ description: "Check the availability of the current device API interface (Connection Status)"
1990
+ },
1991
+ "get-application-list": {
1992
+ fn: applicationHandlers.getApplicationList,
1993
+ description: "Get the list of applications (categories)"
1994
+ },
1995
+ "create-proxy": {
1996
+ fn: proxyHandlers.createProxy,
1997
+ description: "Create the proxy"
1998
+ },
1999
+ "update-proxy": {
2000
+ fn: proxyHandlers.updateProxy,
2001
+ description: "Update the proxy"
2002
+ },
2003
+ "get-proxy-list": {
2004
+ fn: proxyHandlers.getProxyList,
2005
+ description: "Get the list of proxies"
2006
+ },
2007
+ "delete-proxy": {
2008
+ fn: proxyHandlers.deleteProxy,
2009
+ description: "Delete the proxy"
2010
+ },
2011
+ "get-tag-list": {
2012
+ fn: tagHandlers.getTagList,
2013
+ description: "Get the list of browser tags"
2014
+ },
2015
+ "create-tag": {
2016
+ fn: tagHandlers.createTag,
2017
+ description: "Create browser tags (batch supported)"
2018
+ },
2019
+ "update-tag": {
2020
+ fn: tagHandlers.updateTag,
2021
+ description: "Update browser tags (batch supported)"
2022
+ },
2023
+ "delete-tag": {
2024
+ fn: tagHandlers.deleteTag,
2025
+ description: "Delete browser tags"
2026
+ },
2027
+ "download-kernel": {
2028
+ fn: kernelHandlers.downloadKernel,
2029
+ description: "Download or update a browser kernel version"
2030
+ },
2031
+ "get-kernel-list": {
2032
+ fn: kernelHandlers.getKernelList,
2033
+ description: "Get browser kernel list by type or all"
2034
+ },
2035
+ "update-patch": {
2036
+ fn: patchHandlers.updatePatch,
2037
+ description: "Update AdsPower to latest patch version"
2038
+ }
1455
2039
  };
1456
2040
  var SINGLE_PROFILE_ID_COMMANDS = {
1457
2041
  "open-browser": "profileId",
@@ -1460,56 +2044,90 @@ var SINGLE_PROFILE_ID_COMMANDS = {
1460
2044
  "get-browser-active": "profileId"
1461
2045
  };
1462
2046
  var SINGLE_PROFILE_ID_ARRAY_COMMANDS = ["get-profile-ua", "new-fingerprint"];
1463
- function parseArgv(argv) {
1464
- let i = 0;
1465
- while (i < argv.length) {
1466
- if (argv[i] === "--port" || argv[i] === "--api-key") {
1467
- i += 2;
1468
- continue;
1469
- }
1470
- break;
1471
- }
1472
- const command = argv[i];
1473
- const arg = argv[i + 1];
1474
- if (!command || !STATELESS_HANDLERS[command]) {
1475
- throw new Error(`Unknown or unsupported command: ${command || "(missing)"}. Supported: ${Object.keys(STATELESS_HANDLERS).join(", ")}`);
1476
- }
1477
- let args = {};
1478
- if (arg) {
1479
- const trimmed = arg.trim();
1480
- if (trimmed.startsWith("{")) {
1481
- try {
1482
- args = JSON.parse(arg);
1483
- } catch {
1484
- throw new Error("Invalid JSON for command args");
2047
+
2048
+ // src/index.ts
2049
+ var program = new import_commander.Command();
2050
+ program.name("adspower-browser").description("CLI and runtime for adspower-browser").version(VERSION);
2051
+ program.command("start").description("Start the adspower runtime").requiredOption("-k, --api-key <apiKey>", "Set the API key for the adspower runtime").addOption(new import_commander.Option("--base-url <baseUrl>", "Set the base URL for the adspower runtime").hideHelp()).addOption(new import_commander.Option("--node-env <nodeEnv>", "Set the node environment for the adspower runtime").hideHelp()).action(async (options) => {
2052
+ if (options.apiKey) {
2053
+ store.setStoreValue("apiKey", options.apiKey);
2054
+ }
2055
+ if (options.baseUrl) {
2056
+ store.setStoreValue("baseUrl", options.baseUrl);
2057
+ }
2058
+ if (options.nodeEnv) {
2059
+ store.setStoreValue("nodeEnv", options.nodeEnv);
2060
+ }
2061
+ await startChild();
2062
+ });
2063
+ program.command("stop").description("Stop the adspower runtime").action(async () => {
2064
+ await stopChild();
2065
+ });
2066
+ program.command("restart").description("Restart the adspower runtime").action(async () => {
2067
+ await restartChild();
2068
+ });
2069
+ program.command("status").description("Get the status of the adspower runtime").action(async () => {
2070
+ getChildStatus();
2071
+ });
2072
+ for (const cmd of Object.keys(STATELESS_HANDLERS)) {
2073
+ const fnc = STATELESS_HANDLERS[cmd].fn;
2074
+ program.command(`${cmd} [params]`).description(STATELESS_HANDLERS[cmd].description).option("-k, --api-key <apiKey>", "Set the API key for the adspower runtime").option("-p, --port <port>", "Set the port for the adspower runtime").action(async (params, options, command) => {
2075
+ const isRun = await hasRunning(options);
2076
+ if (!isRun) {
2077
+ logError("[!] Adspower runtime is not running");
2078
+ const info = `[i] Please run "${(0, import_colors2.green)("adspower-browser start -k <apiKey>")}" to start the adspower runtime`;
2079
+ console.log(info);
2080
+ return;
2081
+ }
2082
+ const { apiKey, port } = getApiKeyAndPort(options);
2083
+ updateConfig(apiKey, port);
2084
+ let args = {};
2085
+ if (params) {
2086
+ const trimmed = params.trim();
2087
+ if (trimmed.startsWith("{")) {
2088
+ try {
2089
+ args = JSON.parse(params);
2090
+ } catch {
2091
+ logError("Invalid JSON for command args");
2092
+ return;
2093
+ }
2094
+ } else if (SINGLE_PROFILE_ID_COMMANDS[command.name()]) {
2095
+ const key = SINGLE_PROFILE_ID_COMMANDS[command.name()];
2096
+ if (!isNaN(Number(trimmed))) {
2097
+ args = { profileNo: Number(trimmed) };
2098
+ } else {
2099
+ args = { profileId: trimmed };
2100
+ }
2101
+ } else if (SINGLE_PROFILE_ID_ARRAY_COMMANDS.includes(command.name())) {
2102
+ args = { profileId: [trimmed] };
2103
+ } else {
2104
+ try {
2105
+ args = JSON.parse(params);
2106
+ } catch {
2107
+ logError(`Command requires JSON args (e.g. '{"key":"value"}') or use a supported shorthand`);
2108
+ return;
2109
+ }
1485
2110
  }
1486
- } else if (SINGLE_PROFILE_ID_COMMANDS[command]) {
1487
- const key = SINGLE_PROFILE_ID_COMMANDS[command];
1488
- args = { [key]: trimmed };
1489
- } else if (SINGLE_PROFILE_ID_ARRAY_COMMANDS.includes(command)) {
1490
- args = { profileId: [trimmed] };
1491
- } else {
1492
- try {
1493
- args = JSON.parse(arg);
1494
- } catch {
1495
- throw new Error(`Command requires JSON args (e.g. '{"key":"value"}') or use a supported shorthand`);
2111
+ }
2112
+ logSuccess(`Executing command: ${command.name()}, params: ${JSON.stringify(args)}`);
2113
+ const loading = createLoading(`Executing ${command.name()}...`);
2114
+ try {
2115
+ const result = await fnc(args);
2116
+ const out = typeof result === "string" ? result : JSON.stringify(result, null, 2);
2117
+ logInfo(`
2118
+
2119
+ ${out}
2120
+ `);
2121
+ if (command.name() === "update-patch") {
2122
+ await sleepTime(1e3 * 60);
2123
+ await restartChild();
1496
2124
  }
2125
+ } finally {
2126
+ loading.stop();
1497
2127
  }
1498
- }
1499
- return { command, args };
1500
- }
1501
- async function main() {
1502
- const argv = process.argv.slice(2);
1503
- try {
1504
- const { command, args } = parseArgv(argv);
1505
- const handler = STATELESS_HANDLERS[command];
1506
- const result = await handler(args);
1507
- const out = typeof result === "string" ? result : JSON.stringify(result, null, 2);
1508
- process.stdout.write(out + "\n");
1509
- } catch (err) {
1510
- const msg = err instanceof Error ? err.message : String(err);
1511
- process.stderr.write(msg + "\n");
1512
- process.exit(1);
1513
- }
2128
+ });
1514
2129
  }
1515
- main();
2130
+ program.parseAsync(process.argv).catch((error) => {
2131
+ console.error(error);
2132
+ process.exit(1);
2133
+ });