adspower-browser 2.0.0-beta.0 → 2.0.0-beta.2
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/README.MD +85 -35
- package/cli/index.js +73 -10
- package/cwd/lib/main.min.js +2 -2
- package/package.json +4 -2
package/README.MD
CHANGED
|
@@ -8,6 +8,16 @@ AdsPower browser automation CLI for AI agents.
|
|
|
8
8
|
npm install -g adspower-browser
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
After installation, you can use any of these equivalent commands:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
adspower-browser
|
|
15
|
+
adspower
|
|
16
|
+
ads
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`adspower-browser` is the original command name. `adspower` and `ads` are aliases that point to the same CLI entry.
|
|
20
|
+
|
|
11
21
|
## Install as Cursor / Agent Skill
|
|
12
22
|
|
|
13
23
|
Skills live at the repo root. Install with:
|
|
@@ -23,80 +33,120 @@ npx skills add AdsPower/adspower-browser
|
|
|
23
33
|
|
|
24
34
|
Use the CLI in terminal or let the agent run it; the installed skill gives the agent context on when and how to call `adspower-browser` (profiles, groups, proxies, etc.).
|
|
25
35
|
|
|
26
|
-
|
|
27
36
|
## How to Run
|
|
28
37
|
|
|
38
|
+
The examples below use `ads` for brevity, but `adspower-browser` and `adspower` work the same way.
|
|
39
|
+
|
|
29
40
|
```bash
|
|
30
|
-
|
|
41
|
+
ads start -k <KEY>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
If the `ADS_API_KEY` environment variable is set, you can start the CLI directly with the following command.
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
ads start
|
|
31
48
|
```
|
|
32
49
|
|
|
33
50
|
**Two forms for `<arg>`:**
|
|
34
51
|
|
|
35
52
|
1. **Single value (shorthand)** — for profile-related commands, pass one profile ID or number:
|
|
36
|
-
- `
|
|
37
|
-
- `
|
|
38
|
-
- `
|
|
39
|
-
- `
|
|
40
|
-
- `
|
|
41
|
-
- `
|
|
53
|
+
- `ads open-browser <ProfileId>`
|
|
54
|
+
- `ads close-browser <ProfileId>`
|
|
55
|
+
- `ads get-profile-cookies <ProfileId>`
|
|
56
|
+
- `ads get-browser-active <ProfileId>`
|
|
57
|
+
- `ads get-profile-ua <ProfileId>` (single ID)
|
|
58
|
+
- `ads new-fingerprint <ProfileId>` (single ID)
|
|
42
59
|
|
|
43
60
|
2. **JSON string** — full parameters for any command (see Command Reference below):
|
|
44
|
-
- `
|
|
61
|
+
- `ads open-browser '{"profileId":"abc123","launchArgs":"..."}'`
|
|
45
62
|
- Commands with no params: omit `<arg>` or use `'{}'`.
|
|
46
63
|
|
|
47
|
-
## Essential Commands
|
|
64
|
+
## Essential Commands With CLI
|
|
65
|
+
|
|
66
|
+
You can use `ads -h` or `ads <command> -h` to view the specific parameters.
|
|
67
|
+
|
|
68
|
+
### Start and stop CLI
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
ads start -k <KEY> # Start the adspower runtime
|
|
72
|
+
ads stop # Stop the adspower runtime
|
|
73
|
+
ads restart # Restart the adspower runtime
|
|
74
|
+
ads status # Get the status of the adspower runtime
|
|
75
|
+
```
|
|
48
76
|
|
|
49
77
|
### Browser profile – open/close
|
|
50
78
|
|
|
51
79
|
```bash
|
|
52
|
-
|
|
53
|
-
|
|
80
|
+
ads open-browser <profileId> # Or JSON: profileId, profileNo?, ipTab?, launchArgs?, clearCacheAfterClosing?, cdpMask?
|
|
81
|
+
ads close-browser <profileId> # Or JSON: profileId? | profileNo? (one required)
|
|
54
82
|
```
|
|
55
83
|
|
|
56
84
|
### Browser profile – create/update/delete/list
|
|
57
85
|
|
|
58
86
|
```bash
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
87
|
+
ads create-browser '{"groupId":"0","proxyid":"random",...}' # groupId + account field + proxy required
|
|
88
|
+
ads update-browser '{"profileId":"...",...}' # profileId required
|
|
89
|
+
ads delete-browser '{"profileIds":["..."]}' # profileIds required
|
|
90
|
+
ads get-browser-list '{}' # Or groupId?, limit?, page?, profileId?, profileNo?, sortType?, sortOrder?
|
|
91
|
+
ads get-opened-browser # No params
|
|
64
92
|
```
|
|
65
93
|
|
|
66
94
|
### Browser profile – move/cookies/UA/fingerprint/cache/share/active
|
|
67
95
|
|
|
68
96
|
```bash
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
97
|
+
ads move-browser '{"groupId":"1","userIds":["..."]}' # groupId + userIds required
|
|
98
|
+
ads get-profile-cookies <profileId> # Or JSON: profileId? | profileNo?
|
|
99
|
+
ads get-profile-ua <profileId> # Or JSON: profileId[]? | profileNo[]? (up to 10)
|
|
100
|
+
ads close-all-profiles # No params
|
|
101
|
+
ads new-fingerprint <profileId> # Or JSON: profileId[]? | profileNo[]? (up to 10)
|
|
102
|
+
ads delete-cache-v2 '{"profileIds":["..."],"type":["cookie","history"]}' # type: local_storage|indexeddb|extension_cache|cookie|history|image_file
|
|
103
|
+
ads share-profile '{"profileIds":["..."],"receiver":"email@example.com"}' # receiver required; shareType?, content?
|
|
104
|
+
ads get-browser-active <profileId> # Or JSON: profileId? | profileNo?
|
|
105
|
+
ads get-cloud-active '{"userIds":"id1,id2"}' # userIds comma-separated, max 100
|
|
78
106
|
```
|
|
79
107
|
|
|
80
108
|
### Group
|
|
81
109
|
|
|
82
110
|
```bash
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
111
|
+
ads create-group '{"groupName":"My Group","remark":"..."}' # groupName required
|
|
112
|
+
ads update-group '{"groupId":"1","groupName":"New Name"}' # groupId + groupName required; remark? (null to clear)
|
|
113
|
+
ads get-group-list '{}' # groupName?, size?, page?
|
|
86
114
|
```
|
|
87
115
|
|
|
88
116
|
### Application (categories)
|
|
89
117
|
|
|
90
118
|
```bash
|
|
91
|
-
|
|
92
|
-
|
|
119
|
+
ads check-status # No params – API availability
|
|
120
|
+
ads get-application-list '{}' # category_id?, page?, limit?
|
|
93
121
|
```
|
|
94
122
|
|
|
95
123
|
### Proxy
|
|
96
124
|
|
|
97
125
|
```bash
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
126
|
+
ads create-proxy '{"proxies":[{"type":"http","host":"127.0.0.1","port":"8080"}]}' # type, host, port required per item
|
|
127
|
+
ads update-proxy '{"proxyId":"...","host":"..."}' # proxyId required
|
|
128
|
+
ads get-proxy-list '{}' # limit?, page?, proxyId?
|
|
129
|
+
ads delete-proxy '{"proxyIds":["..."]}' # proxyIds required, max 100
|
|
102
130
|
```
|
|
131
|
+
|
|
132
|
+
### Tag
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
ads get-tag-list '{}' # limit?, page?, ids?
|
|
136
|
+
ads create-tag '{"tags":[{"name":"test","color":"darkBlue"}]}' # name required, color?: darkBlue|blue|purple|red|yellow|orange|green|lightGreen
|
|
137
|
+
ads update-tag '{"tags":[{"id":"...","name":"test2","color":"yellow"}]}' # id required,name?, color?: darkBlue|blue|purple|red|yellow|orange|green|lightGreen
|
|
138
|
+
ads delete-tag '{"ids":["..."]}' # ids required, max 100
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Kernel
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
ads get-kernel-list '{"kernel_type":"Chrome"}' # kernel_type?:Chrome|Firefox
|
|
145
|
+
ads download-kernel '{"kernel_type":"Chrome","kernel_version":"..."}' # kernel_type:Chrome|Firefox required,kernel_version required
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Update Patch
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
ads update-patch '{"version_type":"stable"}' # version_type?:stable|beta
|
|
152
|
+
```
|
package/cli/index.js
CHANGED
|
@@ -53,6 +53,9 @@ var Store = class {
|
|
|
53
53
|
this.pid = "";
|
|
54
54
|
}
|
|
55
55
|
getStoreValue(key) {
|
|
56
|
+
if (key === "apiKey" && !this.apiKey) {
|
|
57
|
+
return process.env.ADS_API_KEY || "";
|
|
58
|
+
}
|
|
56
59
|
return this[key];
|
|
57
60
|
}
|
|
58
61
|
setStoreValue(key, value) {
|
|
@@ -205,8 +208,12 @@ var getApiKeyAndPort = (options) => {
|
|
|
205
208
|
port
|
|
206
209
|
};
|
|
207
210
|
const processInstance = readPidFile();
|
|
208
|
-
if (!apiKey
|
|
209
|
-
|
|
211
|
+
if (!apiKey) {
|
|
212
|
+
if (processInstance.apiKey) {
|
|
213
|
+
result.apiKey = processInstance.apiKey;
|
|
214
|
+
} else if (process.env.ADS_API_KEY) {
|
|
215
|
+
result.apiKey = process.env.ADS_API_KEY;
|
|
216
|
+
}
|
|
210
217
|
}
|
|
211
218
|
if (!port && processInstance.apiPort) {
|
|
212
219
|
result.port = processInstance.apiPort;
|
|
@@ -274,6 +281,43 @@ var initSqlite3 = () => {
|
|
|
274
281
|
logSuccess(`[i] SQLite file initialized successfully!`);
|
|
275
282
|
}
|
|
276
283
|
};
|
|
284
|
+
var renderKernelProgress = (result) => {
|
|
285
|
+
const status = result.status || "pending";
|
|
286
|
+
const progress = ["completed", "installing"].includes(status) ? 100 : Math.max(0, Math.min(100, Number(result.progress) || 0));
|
|
287
|
+
if (!process.stdout.isTTY) {
|
|
288
|
+
logInfo(`Kernel progress: ${progress}% [${status}]`);
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
const width = 30;
|
|
292
|
+
const filled = Math.round(progress / 100 * width);
|
|
293
|
+
const bar = `${"=".repeat(filled)}${"-".repeat(width - filled)}`;
|
|
294
|
+
process.stdout.write(`\r[${bar}] ${progress.toFixed(0).padStart(3, " ")}% ${status} `);
|
|
295
|
+
};
|
|
296
|
+
var finishKernelProgress = () => {
|
|
297
|
+
if (process.stdout.isTTY) {
|
|
298
|
+
process.stdout.write("\n");
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
var trackKernelDownload = async (fnc, args) => {
|
|
302
|
+
while (true) {
|
|
303
|
+
const result = await fnc(args);
|
|
304
|
+
try {
|
|
305
|
+
const resultJson = JSON.parse(result.replace("Kernel download/update status: ", ""));
|
|
306
|
+
if (resultJson && resultJson.status && ["pending", "downloading", "completed", "installing", "failed"].includes(resultJson.status)) {
|
|
307
|
+
renderKernelProgress(resultJson);
|
|
308
|
+
if (["completed", "failed"].includes(resultJson.status)) {
|
|
309
|
+
finishKernelProgress();
|
|
310
|
+
return result;
|
|
311
|
+
}
|
|
312
|
+
await sleepTime(3e3);
|
|
313
|
+
} else {
|
|
314
|
+
return result;
|
|
315
|
+
}
|
|
316
|
+
} catch (error) {
|
|
317
|
+
return result;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
};
|
|
277
321
|
|
|
278
322
|
// src/core/start.ts
|
|
279
323
|
var getEnv = () => {
|
|
@@ -511,7 +555,7 @@ function parseArgs() {
|
|
|
511
555
|
}
|
|
512
556
|
}
|
|
513
557
|
return {
|
|
514
|
-
port: port || process.env.PORT || "
|
|
558
|
+
port: port || process.env.PORT || "50325",
|
|
515
559
|
apiKey: apiKey || process.env.API_KEY
|
|
516
560
|
};
|
|
517
561
|
}
|
|
@@ -2048,9 +2092,16 @@ var SINGLE_PROFILE_ID_ARRAY_COMMANDS = ["get-profile-ua", "new-fingerprint"];
|
|
|
2048
2092
|
// src/index.ts
|
|
2049
2093
|
var program = new import_commander.Command();
|
|
2050
2094
|
program.name("adspower-browser").description("CLI and runtime for adspower-browser").version(VERSION);
|
|
2051
|
-
program.command("start").description("Start the adspower runtime").
|
|
2095
|
+
program.command("start").description("Start the adspower runtime").option("-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
2096
|
if (options.apiKey) {
|
|
2053
2097
|
store.setStoreValue("apiKey", options.apiKey);
|
|
2098
|
+
} else {
|
|
2099
|
+
const apiKey = process.env.ADS_API_KEY;
|
|
2100
|
+
if (!apiKey) {
|
|
2101
|
+
logError("error: required option '-k, --api-key <apiKey>' not specified");
|
|
2102
|
+
process.exit(1);
|
|
2103
|
+
}
|
|
2104
|
+
store.setStoreValue("apiKey", "");
|
|
2054
2105
|
}
|
|
2055
2106
|
if (options.baseUrl) {
|
|
2056
2107
|
store.setStoreValue("baseUrl", options.baseUrl);
|
|
@@ -2112,15 +2163,27 @@ for (const cmd of Object.keys(STATELESS_HANDLERS)) {
|
|
|
2112
2163
|
logSuccess(`Executing command: ${command.name()}, params: ${JSON.stringify(args)}`);
|
|
2113
2164
|
const loading = createLoading(`Executing ${command.name()}...`);
|
|
2114
2165
|
try {
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2166
|
+
if (command.name() === "download-kernel") {
|
|
2167
|
+
loading.stop();
|
|
2168
|
+
const result = await trackKernelDownload(fnc, args);
|
|
2169
|
+
const out = typeof result === "string" ? result : JSON.stringify(result, null, 2);
|
|
2170
|
+
logInfo(`
|
|
2171
|
+
|
|
2172
|
+
${out}
|
|
2173
|
+
|
|
2174
|
+
`);
|
|
2175
|
+
} else {
|
|
2176
|
+
const result = await fnc(args);
|
|
2177
|
+
const out = typeof result === "string" ? result : JSON.stringify(result, null, 2);
|
|
2178
|
+
logInfo(`
|
|
2118
2179
|
|
|
2119
2180
|
${out}
|
|
2120
2181
|
`);
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2182
|
+
if (command.name() === "update-patch" && !out.includes("The client is already on the latest patch version. No update is required")) {
|
|
2183
|
+
loading.stop();
|
|
2184
|
+
await sleepTime(1e3 * 60);
|
|
2185
|
+
await restartChild();
|
|
2186
|
+
}
|
|
2124
2187
|
}
|
|
2125
2188
|
} finally {
|
|
2126
2189
|
loading.stop();
|