cdpilot 0.5.0 → 0.8.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.
- package/README.md +147 -5
- package/bin/cdpilot.js +149 -0
- package/package.json +40 -9
- package/src/cdpilot.py +5767 -1600
package/README.md
CHANGED
|
@@ -213,10 +213,34 @@ cdpilot throttle slow3g # Simulate slow 3G
|
|
|
213
213
|
cdpilot throttle fast3g # Simulate fast 3G
|
|
214
214
|
cdpilot throttle offline # Go offline
|
|
215
215
|
cdpilot throttle off # Back to normal
|
|
216
|
-
cdpilot proxy <url> # Set proxy
|
|
216
|
+
cdpilot proxy <url> # Set proxy (legacy single-URL form)
|
|
217
217
|
cdpilot proxy off # Remove proxy
|
|
218
|
+
|
|
219
|
+
# v0.7.0: named pools (BrightData, IPRoyal, Anchor, etc.)
|
|
220
|
+
cdpilot proxy add brd "http://USER:PASS@brd.superproxy.io:22225" --geo us
|
|
221
|
+
cdpilot proxy add ipr "http://USER:PASS@geo.iproyal.com:12321" --sticky
|
|
222
|
+
cdpilot proxy use brd # Activate one pool
|
|
223
|
+
cdpilot proxy list # Show pools (credentials redacted)
|
|
224
|
+
cdpilot proxy show [<name>] # Active or named pool URL (redacted)
|
|
225
|
+
cdpilot proxy remove <name> # Drop a pool
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### TLS Fingerprint (v0.8.0)
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
cdpilot tls-check # Probe JA3/JA4/H2 via tls.peet.ws
|
|
232
|
+
cdpilot tls-check --service browserleaks # Alternate echo
|
|
233
|
+
cdpilot tls-check --json # Raw JSON
|
|
218
234
|
```
|
|
219
235
|
|
|
236
|
+
**Known limitation:** v0.8.0 ships the **probe** (`tls-check`) but no in-tree TLS fix.
|
|
237
|
+
There is no Chromium-based TLS-corrected browser that ships as a standalone binary
|
|
238
|
+
exposing `--remote-debugging-port`. Camoufox is Firefox+Juggler (no CDP);
|
|
239
|
+
Patchright / undetected-chromedriver / nodriver are Python/Playwright libraries,
|
|
240
|
+
not standalone browsers. cdpilot's CDP-only architecture is incompatible with all
|
|
241
|
+
of them without a protocol adapter. **Tracking:** v0.9 roadmap (TLS-MITM plugin
|
|
242
|
+
using curl-impersonate semantics, OR BoringSSL-patched Chromium fork).
|
|
243
|
+
|
|
220
244
|
### Request Interception
|
|
221
245
|
|
|
222
246
|
```bash
|
|
@@ -264,10 +288,22 @@ cdpilot session-close [id] # Close session
|
|
|
264
288
|
### Advanced
|
|
265
289
|
|
|
266
290
|
```bash
|
|
267
|
-
cdpilot cookies [domain]
|
|
268
|
-
cdpilot cookies save <file> [<domain>]
|
|
269
|
-
|
|
270
|
-
cdpilot cookies
|
|
291
|
+
cdpilot cookies [domain] # List cookies (filter by domain)
|
|
292
|
+
cdpilot cookies save <file> [<domain>] # Export cookies as JSON
|
|
293
|
+
cdpilot cookies load <file> # Import cookies (replay CF clearance)
|
|
294
|
+
cdpilot cookies save --host x.com # Save to per-host cache
|
|
295
|
+
cdpilot cookies load --host x.com # Load from per-host cache
|
|
296
|
+
cdpilot cookies list # Cached hosts + age + CF clearance flag
|
|
297
|
+
cdpilot cookies clear --host x.com # Remove one host
|
|
298
|
+
cdpilot cookies clear --all # Wipe entire cache
|
|
299
|
+
cdpilot cookies clear --older-than 7d # Remove stale entries
|
|
300
|
+
cdpilot cookies auto on # Toggle global auto-save/replay flag (v0.6.1: requires safe-list)
|
|
301
|
+
cdpilot cookies auto add <host> # Opt host into auto save/replay (v0.6.1)
|
|
302
|
+
cdpilot cookies auto remove <host> # Remove host from safe-list
|
|
303
|
+
cdpilot cookies auto list # Enable flag + current safe-list
|
|
304
|
+
cdpilot cookies cf-replay <url> # Inject cached CF clearance before nav
|
|
305
|
+
cdpilot wipe [--cookies|--storage|--tabs|--keep h1,h2]
|
|
306
|
+
# v0.6.2: per-task state hygiene (cross-task contamination)
|
|
271
307
|
cdpilot storage # localStorage contents
|
|
272
308
|
cdpilot upload <sel> <file> # Upload file to input
|
|
273
309
|
cdpilot multi-eval <js> # Execute JS in all tabs
|
|
@@ -338,6 +374,41 @@ cdpilot adaptive clear # Drop the stealth host memory entirely
|
|
|
338
374
|
> when it sees one — adds the host to a persistent list, retries once with
|
|
339
375
|
> stealth on. Never auto-demotes. Conservative by design.
|
|
340
376
|
|
|
377
|
+
### Captcha Solver Plugins (v0.6+)
|
|
378
|
+
|
|
379
|
+
Optional integration with 2captcha, anti-captcha, and capmonster. Per-solve
|
|
380
|
+
cost ~$0.001–0.003. API keys stored in `~/.cdpilot/captcha-providers.json`
|
|
381
|
+
(chmod 600) — **never committed to git**.
|
|
382
|
+
|
|
383
|
+
```bash
|
|
384
|
+
# One-time setup
|
|
385
|
+
cdpilot captcha config --provider 2captcha --api-key YOUR_KEY
|
|
386
|
+
cdpilot captcha config --provider anticaptcha --api-key YOUR_KEY # fallback
|
|
387
|
+
|
|
388
|
+
# Enable auto-solve (adaptive layer auto-solves on detect)
|
|
389
|
+
cdpilot captcha auto on
|
|
390
|
+
|
|
391
|
+
# Manual solve (debug / scripting)
|
|
392
|
+
cdpilot captcha solve --type recaptcha-v2 --site-key SK --url https://example.com
|
|
393
|
+
# returns: {"token": "03AGdBq2...", "duration_ms": 12500, "cost": 0.003, "provider": "2captcha"}
|
|
394
|
+
|
|
395
|
+
cdpilot captcha solve --type hcaptcha --site-key SK --url URL
|
|
396
|
+
cdpilot captcha solve --type turnstile --site-key SK --url URL
|
|
397
|
+
cdpilot captcha solve --type funcaptcha --site-key SK --url URL
|
|
398
|
+
|
|
399
|
+
# Status & balance
|
|
400
|
+
cdpilot captcha status # {"configured": [...], "preferred": "2captcha", "auto_enabled": true}
|
|
401
|
+
cdpilot captcha balance # {"2captcha": 1.23, "anticaptcha": 0.50}
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
Supported types: `recaptcha-v2`, `recaptcha-v3`, `hcaptcha`, `turnstile`, `funcaptcha`
|
|
405
|
+
|
|
406
|
+
Tokens are injected via `Runtime.evaluate` CDP — no browser-side libraries required.
|
|
407
|
+
When `captcha auto on` is set, the adaptive layer detects and solves automatically
|
|
408
|
+
after each navigation. Without auto-on, detection still works but solving is manual.
|
|
409
|
+
|
|
410
|
+
> **Expected bench improvement (v0.6):** reCaptcha 2/6 → 5+/6, hCaptcha 2/3 → 3/3
|
|
411
|
+
|
|
341
412
|
Verified against public bot-detection panels:
|
|
342
413
|
- **bot.sannysoft.com:** 24/24 PASS (WebDriver, Chrome obj, Plugins as PluginArray, WebGL, PHANTOM_*, HEADCHR_*, SELENIUM_DRIVER)
|
|
343
414
|
- **bot.incolumitas.com** intoli: 6/6 OK — new-tests: 6/7 OK (one FAIL = pure CDP presence, cannot be JS-patched)
|
|
@@ -422,6 +493,54 @@ print(result.stdout)
|
|
|
422
493
|
|
|
423
494
|
**No Puppeteer. No Playwright. No Selenium.** Just direct CDP communication.
|
|
424
495
|
|
|
496
|
+
## Stealth Bench V1
|
|
497
|
+
|
|
498
|
+
`cdpilot` is benchmarked against a suite of 80 high-friction web tasks to measure success rates against modern anti-bot systems. Gemini 2.5 Flash drives `cdpilot` as the controller; success is defined as full task completion without interception.
|
|
499
|
+
|
|
500
|
+
### v0.5.3 Results (current)
|
|
501
|
+
|
|
502
|
+
| Category | Success / Total | Rate |
|
|
503
|
+
| :--- | :--- | :--- |
|
|
504
|
+
| Custom Antibot | 5 / 5 | 100.0% |
|
|
505
|
+
| Temu Slider | 1 / 1 | 100.0% |
|
|
506
|
+
| hCaptcha | 2 / 3 | 67.0% |
|
|
507
|
+
| Cloudflare | 12 / 22 | 55.0% |
|
|
508
|
+
| DataDome | 5 / 13 | 38.0% |
|
|
509
|
+
| reCaptcha | 2 / 6 | 33.0% |
|
|
510
|
+
| Akamai | 1 / 6 | 17.0% |
|
|
511
|
+
| PerimeterX | 2 / 18 | 11.0% |
|
|
512
|
+
| GeeTest | 0 / 4 | 0.0% |
|
|
513
|
+
| Shape | 0 / 1 | 0.0% |
|
|
514
|
+
| Kasada | 0 / 1 | 0.0% |
|
|
515
|
+
| **Total** | **30 / 80** | **37.5%** |
|
|
516
|
+
|
|
517
|
+
### Version history
|
|
518
|
+
|
|
519
|
+
| Version | Mode | Total | Rate |
|
|
520
|
+
| :--- | :--- | :--- | :--- |
|
|
521
|
+
| v0.5.0 | Baseline (stealth off / adaptive off) | 30 / 80 | 37.5% |
|
|
522
|
+
| v0.5.0 | Stealth only (stealth on / adaptive off) | 32 / 80 | 40.0% |
|
|
523
|
+
| v0.5.0 | Full (stealth on / adaptive on) | 26 / 80 | 32.5% |
|
|
524
|
+
| v0.5.1 | Full — regression fix | 29 / 80 | 36.25% |
|
|
525
|
+
| v0.5.2 | Full — entropy auto-hook | 28 / 80 | 35.0% |
|
|
526
|
+
| v0.5.3 | Full — entropy scope tightened | 30 / 80 | 37.5% |
|
|
527
|
+
| v0.6.0 | + captcha solver + cookies-auto (regression) | 15 / 80 | 18.75% |
|
|
528
|
+
| **v0.8.0** | **Full — cookies safe-host scoped + per-task wipe (no proxy, no TLS fork)** | **29 / 80** | **36.25%** |
|
|
529
|
+
| v0.7.0 (slot) | + named proxy pools | _depends on user proxy_ | — |
|
|
530
|
+
| v0.8.0 (slot) | + TLS-aware launcher (camoufox/undetected-chrome) | _depends on browser choice_ | — |
|
|
531
|
+
|
|
532
|
+
**What cdpilot does not do:** `cdpilot` is an avoidance engine, not a CAPTCHA solver. We prioritize structural stealth (JS fingerprinting, behavioral entropy) to prevent challenges from appearing. When a CAPTCHA blocks progress and cannot be bypassed, the task fails — that is the honest definition of our success rate. PerimeterX (2/18), GeeTest (0/4) and Akamai (1/6) are known weaknesses; v0.7+ (residential proxy) and v0.8+ (TLS fingerprint correction via camoufox) target these directly.
|
|
533
|
+
|
|
534
|
+
## Recommended Configuration
|
|
535
|
+
|
|
536
|
+
Based on Stealth Bench V1 results:
|
|
537
|
+
|
|
538
|
+
- **Speed-first** (most use cases): `cdpilot launch` — default browser behavior, no patches
|
|
539
|
+
- **Stealth-on** (RECOMMENDED, best overall): `cdpilot launch && cdpilot stealth on`
|
|
540
|
+
- **Full adaptive** (specific captcha-heavy workflows): `cdpilot launch && cdpilot stealth on && cdpilot adaptive on`
|
|
541
|
+
|
|
542
|
+
The full adaptive layer is bench-neutral vs baseline (30/80 vs 30/80) for Stealth Bench V1's task mix. Stealth-only (32/80 = 40%) is still the best-performing single variant. For your specific workload, profile both and pick.
|
|
543
|
+
|
|
425
544
|
## Comparison
|
|
426
545
|
|
|
427
546
|
| Feature | cdpilot | Puppeteer | Playwright | Selenium |
|
|
@@ -453,6 +572,29 @@ Future paid offerings:
|
|
|
453
572
|
|
|
454
573
|
Found a vulnerability? Please email the maintainer directly instead of opening a public issue.
|
|
455
574
|
|
|
575
|
+
## Cookie Persistence (v0.6+)
|
|
576
|
+
|
|
577
|
+
Per-host cookie cache with auto-replay before navigation. Particularly useful for
|
|
578
|
+
sites with expensive challenges (Cloudflare, DataDome) — once passed, clearance
|
|
579
|
+
cookies (`cf_clearance`, `__cf_bm`) are cached and replayed on next visit.
|
|
580
|
+
|
|
581
|
+
```bash
|
|
582
|
+
# Enable auto-mode — cookies saved/replayed on every navigate
|
|
583
|
+
cdpilot cookies auto on
|
|
584
|
+
|
|
585
|
+
# Manual per-host workflow
|
|
586
|
+
cdpilot cookies save --host x.com # cache current session cookies
|
|
587
|
+
cdpilot cookies load --host x.com # inject before navigating
|
|
588
|
+
cdpilot cookies cf-replay https://x.com # explicit CF clearance injection
|
|
589
|
+
|
|
590
|
+
# Inspect and clean
|
|
591
|
+
cdpilot cookies list # all cached hosts + age + CF flag
|
|
592
|
+
cdpilot cookies clear --older-than 7d # prune stale cache
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
Storage: `~/.cdpilot/cookies/<host>/cookies.json` (chmod 600, never committed to git).
|
|
596
|
+
Expired cookies are filtered automatically on load.
|
|
597
|
+
|
|
456
598
|
## Roadmap
|
|
457
599
|
|
|
458
600
|
The only browser MCP with built-in test assertions. Here's what we've shipped and what's next:
|
package/bin/cdpilot.js
CHANGED
|
@@ -374,8 +374,157 @@ function showHelp() {
|
|
|
374
374
|
`);
|
|
375
375
|
}
|
|
376
376
|
|
|
377
|
+
// ── Internal Test Runner ──
|
|
378
|
+
|
|
379
|
+
function runInternalTestRunner(testFile, traceDir, traceMode, grepPattern) {
|
|
380
|
+
if (traceDir) {
|
|
381
|
+
fs.mkdirSync(path.join(traceDir, 'screenshots'), { recursive: true });
|
|
382
|
+
fs.mkdirSync(path.join(traceDir, 'a11y'), { recursive: true });
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
const metaPath = traceDir ? path.join(traceDir, 'meta.json') : null;
|
|
386
|
+
const stepsPath = traceDir && traceMode !== 'off' ? path.join(traceDir, 'steps.jsonl') : null;
|
|
387
|
+
|
|
388
|
+
const meta = { name: path.basename(testFile), started_at: new Date().toISOString(), status: 'running', tests: [] };
|
|
389
|
+
if (metaPath) fs.writeFileSync(metaPath, JSON.stringify(meta, null, 2));
|
|
390
|
+
|
|
391
|
+
const testQueue = [];
|
|
392
|
+
global.test = (name, fn) => testQueue.push({ name, fn });
|
|
393
|
+
|
|
394
|
+
try {
|
|
395
|
+
require(path.resolve(testFile));
|
|
396
|
+
} catch (err) {
|
|
397
|
+
const out = { passed: 0, failed: 1, skipped: 0, tests: [{ name: testFile, status: 'failed', duration_ms: 0, error: err.message }] };
|
|
398
|
+
process.stdout.write(JSON.stringify(out) + '\n');
|
|
399
|
+
process.exit(1);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
const results = { passed: 0, failed: 0, skipped: 0, tests: [] };
|
|
403
|
+
const cdpPort = process.env.CDP_PORT || '9222';
|
|
404
|
+
const SCRIPT = path.join(__dirname, '..', 'src', 'cdpilot.py');
|
|
405
|
+
const python = 'python3';
|
|
406
|
+
let stepIdx = 0;
|
|
407
|
+
|
|
408
|
+
const makeT = () => {
|
|
409
|
+
const runCmd = (cmd, ...cargs) => {
|
|
410
|
+
const padded = String(stepIdx).padStart(3, '0');
|
|
411
|
+
const step = { action: cmd + ' ' + cargs.join(' '), ts_ms: Date.now(), duration_ms: 0, error: null };
|
|
412
|
+
const t0 = Date.now();
|
|
413
|
+
try {
|
|
414
|
+
const quoted = cargs.map(a => JSON.stringify(String(a))).join(' ');
|
|
415
|
+
execSync(`${python} ${SCRIPT} ${cmd} ${quoted}`, {
|
|
416
|
+
stdio: 'pipe',
|
|
417
|
+
env: { ...process.env, CDP_PORT: cdpPort },
|
|
418
|
+
timeout: 30000,
|
|
419
|
+
});
|
|
420
|
+
step.duration_ms = Date.now() - t0;
|
|
421
|
+
if (stepsPath) fs.appendFileSync(stepsPath, JSON.stringify(step) + '\n');
|
|
422
|
+
// Screenshot after each step (best-effort — no browser = skipped)
|
|
423
|
+
if (traceDir && traceMode !== 'off') {
|
|
424
|
+
try {
|
|
425
|
+
const shotPath = path.join(traceDir, 'screenshots', `step-${padded}.png`);
|
|
426
|
+
execSync(`${python} ${SCRIPT} shot ${shotPath}`, { stdio: 'pipe', env: { ...process.env, CDP_PORT: cdpPort }, timeout: 10000 });
|
|
427
|
+
} catch (_) { /* no browser is OK in unit-style tests */ }
|
|
428
|
+
}
|
|
429
|
+
stepIdx++;
|
|
430
|
+
} catch (err) {
|
|
431
|
+
step.duration_ms = Date.now() - t0;
|
|
432
|
+
step.error = err.stderr ? err.stderr.toString().trim() : err.message;
|
|
433
|
+
if (stepsPath) fs.appendFileSync(stepsPath, JSON.stringify(step) + '\n');
|
|
434
|
+
stepIdx++;
|
|
435
|
+
throw new Error(`${cmd} failed: ${step.error}`);
|
|
436
|
+
}
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
const t = {
|
|
440
|
+
goto: (url) => runCmd('go', url),
|
|
441
|
+
click: (sel) => runCmd('click', sel),
|
|
442
|
+
fill: (sel, val) => runCmd('fill', sel, val),
|
|
443
|
+
type: (sel, val) => runCmd('type', sel, val),
|
|
444
|
+
hover: (sel) => runCmd('hover', sel),
|
|
445
|
+
screenshot: (p) => runCmd('shot', p),
|
|
446
|
+
eval: (js) => {
|
|
447
|
+
try {
|
|
448
|
+
const out = execSync(`${python} ${SCRIPT} eval ${JSON.stringify(js)}`, { stdio: 'pipe', env: { ...process.env, CDP_PORT: cdpPort }, timeout: 10000 });
|
|
449
|
+
return out.toString().trim();
|
|
450
|
+
} catch (e) { throw new Error('eval failed: ' + e.message); }
|
|
451
|
+
},
|
|
452
|
+
a11y: () => runCmd('a11y-snapshot'),
|
|
453
|
+
};
|
|
454
|
+
|
|
455
|
+
t.expect = (textOrSel) => runCmd('assert', textOrSel);
|
|
456
|
+
t.expect.url = (expected) => runCmd('assert-url', expected);
|
|
457
|
+
t.expect.visible = (sel) => runCmd('assert-visible', sel);
|
|
458
|
+
t.expect.hidden = (sel) => runCmd('assert-hidden', sel);
|
|
459
|
+
|
|
460
|
+
return t;
|
|
461
|
+
};
|
|
462
|
+
|
|
463
|
+
// Run tests sequentially (parallel is managed at the Python level across files)
|
|
464
|
+
const runAll = async () => {
|
|
465
|
+
for (const tst of testQueue) {
|
|
466
|
+
if (grepPattern && !tst.name.match(new RegExp(grepPattern, 'i'))) {
|
|
467
|
+
results.skipped++;
|
|
468
|
+
continue;
|
|
469
|
+
}
|
|
470
|
+
const t0 = Date.now();
|
|
471
|
+
const rec = { name: tst.name, status: 'passed', duration_ms: 0, error: null };
|
|
472
|
+
try {
|
|
473
|
+
await tst.fn(makeT());
|
|
474
|
+
rec.status = 'passed';
|
|
475
|
+
results.passed++;
|
|
476
|
+
} catch (err) {
|
|
477
|
+
rec.status = 'failed';
|
|
478
|
+
rec.error = err.message;
|
|
479
|
+
results.failed++;
|
|
480
|
+
}
|
|
481
|
+
rec.duration_ms = Date.now() - t0;
|
|
482
|
+
results.tests.push(rec);
|
|
483
|
+
if (metaPath) {
|
|
484
|
+
meta.tests.push(rec);
|
|
485
|
+
meta.status = 'running';
|
|
486
|
+
fs.writeFileSync(metaPath, JSON.stringify(meta, null, 2));
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
// Finalize meta
|
|
491
|
+
if (metaPath) {
|
|
492
|
+
meta.status = results.failed > 0 ? 'failed' : 'passed';
|
|
493
|
+
meta.passed = results.passed;
|
|
494
|
+
meta.failed = results.failed;
|
|
495
|
+
meta.skipped = results.skipped;
|
|
496
|
+
meta.ended_at = new Date().toISOString();
|
|
497
|
+
fs.writeFileSync(metaPath, JSON.stringify(meta, null, 2));
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
process.stdout.write(JSON.stringify(results) + '\n');
|
|
501
|
+
process.exit(results.failed > 0 ? 1 : 0);
|
|
502
|
+
};
|
|
503
|
+
|
|
504
|
+
runAll().catch(err => {
|
|
505
|
+
process.stderr.write('Test runner error: ' + err.message + '\n');
|
|
506
|
+
process.exit(1);
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
|
|
377
510
|
// ── Main ──
|
|
378
511
|
|
|
512
|
+
// Internal test runner mode — intercept before normal CLI dispatch
|
|
513
|
+
if (process.argv.includes('--internal-test-runner')) {
|
|
514
|
+
const idx = process.argv.indexOf('--internal-test-runner');
|
|
515
|
+
const testFile = process.argv[idx + 1];
|
|
516
|
+
const traceDirArg = process.argv.find(a => a.startsWith('--trace-dir='));
|
|
517
|
+
const traceArg = process.argv.find(a => a.startsWith('--trace='));
|
|
518
|
+
const grepArg = process.argv.find(a => a.startsWith('--grep='));
|
|
519
|
+
runInternalTestRunner(
|
|
520
|
+
testFile,
|
|
521
|
+
traceDirArg ? traceDirArg.split('=').slice(1).join('=') : null,
|
|
522
|
+
traceArg ? traceArg.split('=')[1] : 'default',
|
|
523
|
+
grepArg ? grepArg.split('=').slice(1).join('=') : null,
|
|
524
|
+
);
|
|
525
|
+
return; // runAll() is async, this exits via process.exit
|
|
526
|
+
}
|
|
527
|
+
|
|
379
528
|
const args = process.argv.slice(2);
|
|
380
529
|
const cmd = args[0];
|
|
381
530
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cdpilot",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Zero-dependency browser automation
|
|
3
|
+
"version": "0.8.0",
|
|
4
|
+
"description": "Zero-dependency browser automation CLI. Raw CDP, 60+ commands, stealth + adaptive escalation, CAPTCHA solvers, proxy pools, TLS probe, MCP server. No Puppeteer/Playwright/Selenium.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"cdpilot": "./bin/cdpilot.js",
|
|
7
7
|
"bctl": "./bin/cdpilot.js"
|
|
@@ -11,12 +11,38 @@
|
|
|
11
11
|
"start": "node bin/cdpilot.js"
|
|
12
12
|
},
|
|
13
13
|
"keywords": [
|
|
14
|
-
"browser-automation",
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
14
|
+
"browser-automation",
|
|
15
|
+
"cdp",
|
|
16
|
+
"chrome-devtools-protocol",
|
|
17
|
+
"cli",
|
|
18
|
+
"mcp",
|
|
19
|
+
"ai-agent",
|
|
20
|
+
"web-scraping",
|
|
21
|
+
"zero-dependency",
|
|
22
|
+
"headless-browser",
|
|
23
|
+
"puppeteer-alternative",
|
|
24
|
+
"playwright-alternative",
|
|
25
|
+
"screenshot",
|
|
26
|
+
"pdf",
|
|
27
|
+
"automation",
|
|
28
|
+
"devtools",
|
|
29
|
+
"browser",
|
|
30
|
+
"model-context-protocol",
|
|
31
|
+
"claude",
|
|
32
|
+
"brave",
|
|
33
|
+
"testing",
|
|
34
|
+
"web-testing",
|
|
35
|
+
"accessibility",
|
|
36
|
+
"a11y",
|
|
37
|
+
"stealth",
|
|
38
|
+
"captcha-solver",
|
|
39
|
+
"anti-bot",
|
|
40
|
+
"cloudflare-bypass",
|
|
41
|
+
"datadome",
|
|
42
|
+
"adaptive-escalation",
|
|
43
|
+
"proxy-rotation",
|
|
44
|
+
"tls-fingerprint",
|
|
45
|
+
"cookie-management"
|
|
20
46
|
],
|
|
21
47
|
"author": "Mehmet Nadir",
|
|
22
48
|
"license": "MIT",
|
|
@@ -32,5 +58,10 @@
|
|
|
32
58
|
"src/cdpilot.py",
|
|
33
59
|
"README.md",
|
|
34
60
|
"LICENSE"
|
|
35
|
-
]
|
|
61
|
+
],
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"gray-matter": "^4.0.3",
|
|
64
|
+
"remark": "^15.0.1",
|
|
65
|
+
"remark-html": "^16.0.1"
|
|
66
|
+
}
|
|
36
67
|
}
|