@apitap/core 1.5.2 → 1.5.4
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 +28 -8
- package/dist/auth/handoff.js +1 -1
- package/dist/auth/handoff.js.map +1 -1
- package/dist/capture/cdp-attach.d.ts +60 -0
- package/dist/capture/cdp-attach.js +422 -0
- package/dist/capture/cdp-attach.js.map +1 -0
- package/dist/capture/filter.js +6 -0
- package/dist/capture/filter.js.map +1 -1
- package/dist/capture/parameterize.d.ts +7 -6
- package/dist/capture/parameterize.js +204 -12
- package/dist/capture/parameterize.js.map +1 -1
- package/dist/capture/session.js +20 -10
- package/dist/capture/session.js.map +1 -1
- package/dist/cli.js +15 -0
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +12 -0
- package/dist/mcp.js.map +1 -1
- package/dist/native-host.js +10 -1
- package/dist/native-host.js.map +1 -1
- package/dist/plugin.js +10 -3
- package/dist/plugin.js.map +1 -1
- package/dist/skill/generator.d.ts +7 -1
- package/dist/skill/generator.js +35 -3
- package/dist/skill/generator.js.map +1 -1
- package/package.json +1 -1
- package/src/auth/handoff.ts +1 -1
- package/src/capture/cdp-attach.ts +501 -0
- package/src/capture/filter.ts +5 -0
- package/src/capture/parameterize.ts +207 -11
- package/src/capture/session.ts +20 -10
- package/src/cli.ts +20 -0
- package/src/index.ts +1 -0
- package/src/mcp.ts +12 -0
- package/src/native-host.ts +12 -1
- package/src/plugin.ts +10 -3
- package/src/skill/generator.ts +38 -3
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# ApiTap
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@apitap/core)
|
|
4
|
-
[](https://github.com/n1byn1kt/apitap)
|
|
5
5
|
[](./LICENSE)
|
|
6
6
|
|
|
7
7
|
**The MCP server that turns any website into an API — no docs, no SDK, no browser.**
|
|
@@ -34,13 +34,14 @@ No scraping. No browser. Just the API.
|
|
|
34
34
|
|
|
35
35
|
## How It Works
|
|
36
36
|
|
|
37
|
-
1. **Capture** — Launch a Playwright browser, visit a site, browse normally. ApiTap intercepts all network traffic via CDP.
|
|
37
|
+
1. **Capture** — Launch a Playwright browser, visit a site, browse normally. ApiTap intercepts all network traffic via CDP. Or use `apitap attach` to capture from your already-running Chrome.
|
|
38
38
|
2. **Filter** — Scoring engine separates signal from noise. Analytics, tracking pixels, and framework internals are filtered out. Only real API endpoints survive.
|
|
39
|
-
3. **Generate** — Captured endpoints are grouped by domain, URLs are parameterized (`/users/123` → `/users/:id`), and a JSON skill file is written to `~/.apitap/skills/`.
|
|
39
|
+
3. **Generate** — Captured endpoints are grouped by domain, URLs are parameterized (`/users/123` → `/users/:id` with context-aware semantic names), and a JSON skill file is written to `~/.apitap/skills/`.
|
|
40
40
|
4. **Replay** — Read the skill file, substitute parameters, call the API with `fetch()`. Zero dependencies in the replay path.
|
|
41
41
|
|
|
42
42
|
```
|
|
43
|
-
Capture: Browser → Playwright listener → Filter → Skill Generator → skill.json
|
|
43
|
+
Capture: Browser → Playwright/CDP listener → Filter → Skill Generator → skill.json
|
|
44
|
+
Attach: Running Chrome → CDP attach → Filter → Skill Generator → skill.json
|
|
44
45
|
Replay: Agent → Replay Engine (skill.json) → fetch() → API → JSON response
|
|
45
46
|
```
|
|
46
47
|
|
|
@@ -84,6 +85,22 @@ apitap capture https://polymarket.com --duration 30
|
|
|
84
85
|
|
|
85
86
|
ApiTap opens a browser window. Browse the site normally — click around, scroll, search. Every API call is captured. Press Ctrl+C when done.
|
|
86
87
|
|
|
88
|
+
### Attach to a running Chrome
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
# Enable remote debugging in Chrome: Settings → Remote debugging → toggle on
|
|
92
|
+
|
|
93
|
+
# Attach to your signed-in Chrome — captures all tabs
|
|
94
|
+
apitap attach --port 9222
|
|
95
|
+
|
|
96
|
+
# Filter to specific domains
|
|
97
|
+
apitap attach --port 9222 --domain *.github.com
|
|
98
|
+
|
|
99
|
+
# Ctrl+C to stop — generates signed skill files for each captured domain
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
No separate browser, no re-login. Captures from your real Chrome sessions with all your cookies and auth tokens.
|
|
103
|
+
|
|
87
104
|
### List and explore captured APIs
|
|
88
105
|
|
|
89
106
|
```bash
|
|
@@ -327,7 +344,7 @@ For one-off captures without the passive index:
|
|
|
327
344
|
2. Browse the site — extension records API traffic
|
|
328
345
|
3. Click **Stop** → skill file auto-saves to `~/.apitap/skills/`
|
|
329
346
|
|
|
330
|
-
The popup shows CLI connection status and live capture stats. Auth tokens are automatically
|
|
347
|
+
The popup shows CLI connection status and live capture stats. Auth tokens are encrypted with AES-256-GCM in session storage and automatically persisted to `~/.apitap/auth.enc` via the native host, with `[stored]` placeholders in the exported skill files.
|
|
331
348
|
|
|
332
349
|
> **Note:** Chrome Web Store submission coming soon. For now, load as an unpacked extension in Developer mode.
|
|
333
350
|
|
|
@@ -360,7 +377,7 @@ Skill files are JSON documents stored at `~/.apitap/skills/<domain>.json`. They
|
|
|
360
377
|
|
|
361
378
|
```json
|
|
362
379
|
{
|
|
363
|
-
"version":
|
|
380
|
+
"version": 2,
|
|
364
381
|
"domain": "gamma-api.polymarket.com",
|
|
365
382
|
"baseUrl": "https://gamma-api.polymarket.com",
|
|
366
383
|
"endpoints": [
|
|
@@ -425,7 +442,7 @@ Endpoint replayed
|
|
|
425
442
|
→ Redirect check: if server redirects, validate new target before following
|
|
426
443
|
```
|
|
427
444
|
|
|
428
|
-
**Blocked ranges:** `127.0.0.0/8`, `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `169.254.0.0/16` (cloud metadata), `0.0.0.0`, IPv6 equivalents (`::1`, `fe80::/10`, `fc00::/7`, `::ffff:` mapped addresses), `localhost`, `.local`, `.internal`, `file://`, `javascript:` schemes.
|
|
445
|
+
**Blocked ranges:** `127.0.0.0/8`, `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `169.254.0.0/16` (cloud metadata), `100.64.0.0/10` (CGNAT/Tailscale), `198.18.0.0/15` (benchmarking), `240.0.0.0/4` (reserved), `0.0.0.0`, IPv6 equivalents (`::1`, `fe80::/10`, `fc00::/7`, `::ffff:` mapped addresses), `localhost`, `.local`, `.internal`, `file://`, `javascript:` schemes. Alternative IP representations (decimal integer, octal, hex) are normalized before checking.
|
|
429
446
|
|
|
430
447
|
This is especially relevant now that [MCP servers are being used as attack vectors in the wild](https://cloud.google.com/blog/topics/threat-intelligence/distillation-experimentation-integration-ai-adversarial-use) — Google's Threat Intelligence Group recently documented underground toolkits built on compromised MCP servers. ApiTap is designed to be safe even when processing untrusted inputs.
|
|
431
448
|
|
|
@@ -442,6 +459,7 @@ All commands support `--json` for machine-readable output.
|
|
|
442
459
|
| `apitap read <url>` | Extract content without a browser |
|
|
443
460
|
| `apitap discover <url>` | Detect APIs without launching a browser |
|
|
444
461
|
| `apitap capture <url>` | Capture API traffic from a website |
|
|
462
|
+
| `apitap attach --port <port>` | Attach to running Chrome and capture API traffic |
|
|
445
463
|
| `apitap list` | List available skill files |
|
|
446
464
|
| `apitap show <domain>` | Show endpoints for a domain |
|
|
447
465
|
| `apitap search <query>` | Search skill files by domain or endpoint |
|
|
@@ -452,6 +470,7 @@ All commands support `--json` for machine-readable output.
|
|
|
452
470
|
| `apitap serve <domain>` | Serve a skill file as an MCP server |
|
|
453
471
|
| `apitap inspect <url>` | Discover APIs without saving |
|
|
454
472
|
| `apitap stats` | Show token savings report |
|
|
473
|
+
| `apitap index [domain]` | View passive index from Chrome extension |
|
|
455
474
|
| `apitap audit` | Audit stored skill files and credentials |
|
|
456
475
|
| `apitap forget <domain>` | Remove skill file and credentials for a domain |
|
|
457
476
|
| `apitap --version` | Print version |
|
|
@@ -468,6 +487,7 @@ All commands support `--json` for machine-readable output.
|
|
|
468
487
|
| `--attach` | Only attach to existing browser |
|
|
469
488
|
| `--no-scrub` | Disable PII scrubbing |
|
|
470
489
|
| `--no-verify` | Skip auto-verification of GET endpoints |
|
|
490
|
+
| `--domain <glob>` | Filter traffic by domain glob (attach mode, e.g. `*.github.com`) |
|
|
471
491
|
|
|
472
492
|
## Development
|
|
473
493
|
|
|
@@ -475,7 +495,7 @@ All commands support `--json` for machine-readable output.
|
|
|
475
495
|
git clone https://github.com/n1byn1kt/apitap.git
|
|
476
496
|
cd apitap
|
|
477
497
|
npm install
|
|
478
|
-
npm test #
|
|
498
|
+
npm test # ~1195 tests, Node built-in test runner
|
|
479
499
|
npm run typecheck # Type checking
|
|
480
500
|
npm run build # Compile to dist/
|
|
481
501
|
npx tsx src/cli.ts capture <url> # Run from source
|
package/dist/auth/handoff.js
CHANGED
|
@@ -236,7 +236,7 @@ async function doHandoff(authManager, options) {
|
|
|
236
236
|
const cookieDomain = (c.domain || '').replace(/^\./, ''); // Remove leading dot
|
|
237
237
|
return cookieDomain === domain ||
|
|
238
238
|
cookieDomain.endsWith('.' + domain) ||
|
|
239
|
-
domain.endsWith('.' + cookieDomain);
|
|
239
|
+
(domain.endsWith('.' + cookieDomain) && cookieDomain.includes('.'));
|
|
240
240
|
});
|
|
241
241
|
if (cookies.length === 0 && !authDetected) {
|
|
242
242
|
return {
|
package/dist/auth/handoff.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handoff.js","sourceRoot":"","sources":["../../src/auth/handoff.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"handoff.js","sourceRoot":"","sources":["../../src/auth/handoff.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAuBtD,6CAA6C;AAC7C,MAAM,kBAAkB,GAAG;IACzB,YAAY;IACZ,iBAAiB;IACjB,kBAAkB;IAClB,qBAAqB;IACrB,+BAA+B;CAChC,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CACtC,GAAW,EACX,MAAc,EACd,IAAY;IAEZ,IAAI,MAAM,GAAG,GAAG,IAAI,MAAM,IAAI,GAAG;QAAE,OAAO,IAAI,CAAC;IAC/C,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAE5D,IAAI,MAA+B,CAAC;IACpC,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,OAAO,MAAM,CAAC,YAAY,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAEzD,OAAO;QACL,WAAW,EAAE,MAAM,CAAC,YAAY;QAChC,YAAY,EAAE,OAAO,MAAM,CAAC,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS;QACzF,SAAS,EAAE,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;QAChF,SAAS,EAAE,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;QAChF,KAAK,EAAE,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;KACnE,CAAC;AACJ,CAAC;AAED,oCAAoC;AACpC,MAAM,uBAAuB,GAAG;IAC9B,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ;IAC5C,OAAO,EAAE,YAAY,EAAE,iBAAiB;CACzC,CAAC;AAEF,sEAAsE;AACtE,MAAM,wBAAwB,GAAG;IAC/B,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS;CAChD,CAAC;AAEF,mEAAmE;AACnE,MAAM,yBAAyB,GAAG;IAChC,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,WAAW;CAC5E,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAA4B,EAC5B,MAAc;IAEd,IAAI,MAAM,GAAG,GAAG,IAAI,MAAM,IAAI,GAAG;QAAE,OAAO,KAAK,CAAC;IAEhD,wBAAwB;IACxB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAChD,IAAI,UAAU,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;QACxF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,iCAAiC;IACjC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC5C,IAAI,CAAC,SAAS;QAAE,OAAO,KAAK,CAAC;IAE7B,2CAA2C;IAC3C,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAElD,2BAA2B;IAC3B,IAAI,wBAAwB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAEzE,6BAA6B;IAC7B,OAAO,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED,SAAS,uBAAuB,CAAC,IAAY;IAC3C,OAAO,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AACzD,CAAC;AAED,SAAS,oBAAoB,CAAC,IAAY;IACxC,OAAO,wBAAwB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED,SAAS,qBAAqB,CAAC,IAAY;IACzC,OAAO,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,+BAA+B,CAC7C,oBAAyC,EACzC,cAAsD;IAEtD,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;QACpC,MAAM,QAAQ,GAAG,oBAAoB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACvD,MAAM,YAAY,GAAG,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,MAAM,CAAC,KAAK,CAAC;QACzE,IAAI,CAAC,YAAY;YAAE,OAAO,KAAK,CAAC;QAChC,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QACxD,IAAI,oBAAoB,CAAC,MAAM,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QACpD,IAAI,qBAAqB,CAAC,MAAM,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QACrD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC;AAED,2DAA2D;AAC3D,MAAM,YAAY,GAAG,IAAI,GAAG,EAAkC,CAAC;AAE/D;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,WAAwB,EACxB,OAAuB;IAEvB,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAE3B,qDAAqD;IACrD,MAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1C,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAE9B,MAAM,OAAO,GAAG,SAAS,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAChD,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAElC,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC;IACvB,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC;AAED,KAAK,UAAU,SAAS,CACtB,WAAwB,EACxB,OAAuB;IAEvB,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAC3B,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,WAAW,MAAM,EAAE,CAAC;IACzD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC,YAAY;IAExD,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,aAAa,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IAEtE,IAAI,CAAC;QAEH,6DAA6D;QAC7D,MAAM,aAAa,GAAG,MAAM,WAAW,CAAC,2BAA2B,CAAC,MAAM,CAAC,CAAC;QAC5E,IAAI,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;YACnC,MAAM,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAClD,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QACrC,IAAI,YAAyD,CAAC;QAC9D,IAAI,YAAoC,CAAC;QACzC,IAAI,aAA8C,CAAC;QACnD,IAAI,aAAa,GAAmK,EAAE,CAAC;QAEvL,wEAAwE;QACxE,MAAM,YAAY,GAAG,MAAM,CAAC;QAE5B,mFAAmF;QACnF,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;YACrC,uEAAuE;YACvE,IAAI,OAAe,CAAC;YACpB,IAAI,CAAC;gBACH,OAAO,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC;YACvD,CAAC;YAAC,MAAM,CAAC;gBAAC,OAAO;YAAC,CAAC;YACnB,IAAI,OAAO,KAAK,YAAY,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,GAAG,YAAY,CAAC,EAAE,CAAC;gBACtE,OAAO,CAAC,6BAA6B;YACvC,CAAC;YAED,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC;YAEhD,mCAAmC;YACnC,MAAM,UAAU,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC;YAC/C,IAAI,UAAU,EAAE,CAAC;gBACf,IAAI,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;oBACrC,YAAY,GAAG,QAAQ,CAAC;oBACxB,YAAY,GAAG;wBACb,IAAI,EAAE,QAAQ;wBACd,MAAM,EAAE,eAAe;wBACvB,KAAK,EAAE,UAAU;qBAClB,CAAC;gBACJ,CAAC;qBAAM,IAAI,UAAU,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;oBAC7G,YAAY,GAAG,SAAS,CAAC;oBACzB,YAAY,GAAG;wBACb,IAAI,EAAE,SAAS;wBACf,MAAM,EAAE,eAAe;wBACvB,KAAK,EAAE,UAAU;qBAClB,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,wCAAwC;YACxC,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC;gBACjC,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC;gBAC3B,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG,EAAE,CAAC;oBAC/E,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;oBACnC,MAAM,KAAK,GAAG,wBAAwB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;oBAC1D,IAAI,KAAK,EAAE,CAAC;wBACV,aAAa,GAAG,KAAK,CAAC;oBACxB,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,MAAM,CAAC,CAAC,wCAAwC,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;QAEH,yBAAyB;QACzB,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QAE9E,+CAA+C;QAC/C,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE;YACvB,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YAC7C,MAAM,CAAC,WAAW,GAAG,gFAAgF,CAAC;YACtG,MAAM,CAAC,KAAK,CAAC,OAAO;gBAClB,yDAAyD;oBACzD,uFAAuF;oBACvF,yDAAyD,CAAC;YAC5D,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,CAAC,iDAAiD;QAErE,2EAA2E;QAC3E,uDAAuD;QACvD,MAAM,cAAc,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;YAC5C,IAAI,CAAC;gBACH,aAAa,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;YAC1C,CAAC;YAAC,MAAM,CAAC;gBACP,8CAA8C;YAChD,CAAC;QACH,CAAC,EAAE,IAAI,CAAC,CAAC;QAET,8DAA8D;QAC9D,yEAAyE;QACzE,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAClC,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC3C,OAAO,CAAC,EAAE,CAAC,cAAc,EAAE,GAAG,EAAE;gBAC9B,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,aAAa,CAAC,cAAc,CAAC,CAAC;QAE9B,sEAAsE;QACtE,IAAI,CAAC;YACH,aAAa,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QAC1C,CAAC;QAAC,MAAM,CAAC;YACP,yDAAyD;QAC3D,CAAC;QAED,sEAAsE;QACtE,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;YACvC,MAAM,YAAY,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,qBAAqB;YAC/E,OAAO,YAAY,KAAK,MAAM;gBAC5B,YAAY,CAAC,QAAQ,CAAC,GAAG,GAAG,MAAM,CAAC;gBACnC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,GAAG,YAAY,CAAC,IAAI,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;QAEH,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YAC1C,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,WAAW,EAAE,CAAC;gBACd,KAAK,EAAE,uEAAuE;aAC/E,CAAC;QACJ,CAAC;QAED,wBAAwB;QACxB,MAAM,OAAO,GAAkB;YAC7B,OAAO;YACP,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACjC,QAAQ,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,WAAW;SAC3C,CAAC;QACF,MAAM,WAAW,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAEhD,uDAAuD;QACvD,IAAI,aAAa,EAAE,CAAC;YAClB,YAAY,GAAG;gBACb,IAAI,EAAE,QAAQ;gBACd,MAAM,EAAE,eAAe;gBACvB,KAAK,EAAE,UAAU,aAAa,CAAC,WAAW,EAAE;gBAC5C,GAAG,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC;oBAC5B,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,aAAa,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE;iBAC/E,CAAC,CAAC,CAAC,EAAE,CAAC;aACR,CAAC;YACF,YAAY,GAAG,QAAQ,CAAC;YAExB,IAAI,aAAa,CAAC,YAAY,EAAE,CAAC;gBAC/B,MAAM,WAAW,CAAC,qBAAqB,CAAC,MAAM,EAAE;oBAC9C,YAAY,EAAE,aAAa,CAAC,YAAY;iBACzC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,sCAAsC;QACtC,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QAChD,CAAC;aAAM,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,uBAAuB;YACvB,MAAM,cAAc,GAAG,OAAO;iBAC3B,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;iBAC9D,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAEpE,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9B,YAAY,GAAG,QAAQ,CAAC;gBACxB,MAAM,YAAY,GAAG,cAAc;qBAChC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;qBAChC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACd,MAAM,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE;oBAC9B,IAAI,EAAE,QAAQ;oBACd,MAAM,EAAE,QAAQ;oBAChB,KAAK,EAAE,YAAY;iBACpB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO;YACL,OAAO,EAAE,IAAI;YACb,WAAW,EAAE,OAAO,CAAC,MAAM;YAC3B,YAAY;SACb,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,KAAK;YACd,WAAW,EAAE,CAAC;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAC9D,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACxB,CAAC;QAAC,MAAM,CAAC;YACP,uCAAuC;QACzC,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test if a hostname matches any pattern in a domain glob list.
|
|
3
|
+
* Empty list means "match all" (no filter).
|
|
4
|
+
*
|
|
5
|
+
* Glob rules:
|
|
6
|
+
* - "api.github.com" — exact match
|
|
7
|
+
* - "*.github.com" — matches any subdomain AND the bare domain
|
|
8
|
+
* (the *. prefix means "zero or more subdomains")
|
|
9
|
+
*/
|
|
10
|
+
export declare function matchesDomainGlob(hostname: string, patterns: string[]): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Parse a comma-separated domain pattern string into a list.
|
|
13
|
+
*/
|
|
14
|
+
export declare function parseDomainPatterns(input: string | undefined): string[];
|
|
15
|
+
/**
|
|
16
|
+
* Discover Chrome's browser-level WebSocket URL via the /json/version endpoint.
|
|
17
|
+
*/
|
|
18
|
+
export declare function discoverBrowserWsUrl(port: number): Promise<{
|
|
19
|
+
wsUrl: string;
|
|
20
|
+
browser: string;
|
|
21
|
+
tabCount: number;
|
|
22
|
+
}>;
|
|
23
|
+
/**
|
|
24
|
+
* Minimal CDP session over a single WebSocket.
|
|
25
|
+
* Supports browser-level commands and session-multiplexed target commands
|
|
26
|
+
* (via the sessionId parameter on send/events, using flatten: true).
|
|
27
|
+
*/
|
|
28
|
+
export declare class CDPSession {
|
|
29
|
+
private wsUrl;
|
|
30
|
+
private ws;
|
|
31
|
+
private nextId;
|
|
32
|
+
private callbacks;
|
|
33
|
+
private listeners;
|
|
34
|
+
constructor(wsUrl: string);
|
|
35
|
+
connect(): Promise<void>;
|
|
36
|
+
send(method: string, params?: Record<string, unknown>, sessionId?: string): Promise<Record<string, unknown>>;
|
|
37
|
+
on(event: string, handler: (params: Record<string, unknown>) => void): void;
|
|
38
|
+
close(): void;
|
|
39
|
+
}
|
|
40
|
+
export interface AttachOptions {
|
|
41
|
+
port: number;
|
|
42
|
+
domainPatterns: string[];
|
|
43
|
+
json: boolean;
|
|
44
|
+
onProgress?: (line: string) => void;
|
|
45
|
+
}
|
|
46
|
+
export interface AttachResult {
|
|
47
|
+
domains: Array<{
|
|
48
|
+
domain: string;
|
|
49
|
+
endpoints: number;
|
|
50
|
+
skillFile: string;
|
|
51
|
+
}>;
|
|
52
|
+
totalRequests: number;
|
|
53
|
+
filteredRequests: number;
|
|
54
|
+
duration: number;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Attach to a running Chrome instance via CDP, passively capture API traffic
|
|
58
|
+
* across all tabs, and generate signed skill files on SIGINT.
|
|
59
|
+
*/
|
|
60
|
+
export declare function attach(options: AttachOptions): Promise<AttachResult>;
|
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
// src/capture/cdp-attach.ts
|
|
2
|
+
import http from 'node:http';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { shouldCapture } from './filter.js';
|
|
5
|
+
import { SkillGenerator, deduplicateAuth } from '../skill/generator.js';
|
|
6
|
+
import { signSkillFile } from '../skill/signing.js';
|
|
7
|
+
import { writeSkillFile } from '../skill/store.js';
|
|
8
|
+
import { AuthManager, getMachineId } from '../auth/manager.js';
|
|
9
|
+
import { deriveSigningKey } from '../auth/crypto.js';
|
|
10
|
+
import { join } from 'node:path';
|
|
11
|
+
// ---- Domain glob matching ----
|
|
12
|
+
/**
|
|
13
|
+
* Test if a hostname matches any pattern in a domain glob list.
|
|
14
|
+
* Empty list means "match all" (no filter).
|
|
15
|
+
*
|
|
16
|
+
* Glob rules:
|
|
17
|
+
* - "api.github.com" — exact match
|
|
18
|
+
* - "*.github.com" — matches any subdomain AND the bare domain
|
|
19
|
+
* (the *. prefix means "zero or more subdomains")
|
|
20
|
+
*/
|
|
21
|
+
export function matchesDomainGlob(hostname, patterns) {
|
|
22
|
+
if (patterns.length === 0)
|
|
23
|
+
return true;
|
|
24
|
+
for (const pattern of patterns) {
|
|
25
|
+
if (pattern.startsWith('*.')) {
|
|
26
|
+
const base = pattern.slice(2); // "github.com"
|
|
27
|
+
// Match bare domain or any subdomain
|
|
28
|
+
if (hostname === base || hostname.endsWith('.' + base)) {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
if (hostname === pattern)
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Parse a comma-separated domain pattern string into a list.
|
|
41
|
+
*/
|
|
42
|
+
export function parseDomainPatterns(input) {
|
|
43
|
+
if (!input || input.trim() === '')
|
|
44
|
+
return [];
|
|
45
|
+
return input.split(',').map(p => p.trim()).filter(p => p.length > 0);
|
|
46
|
+
}
|
|
47
|
+
// ---- CDP HTTP discovery ----
|
|
48
|
+
function cdpGet(url) {
|
|
49
|
+
return new Promise((resolve, reject) => {
|
|
50
|
+
http.get(url, (res) => {
|
|
51
|
+
let data = '';
|
|
52
|
+
res.on('data', (chunk) => data += chunk);
|
|
53
|
+
res.on('end', () => {
|
|
54
|
+
try {
|
|
55
|
+
resolve(JSON.parse(data));
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
reject(new Error(`Invalid JSON from ${url}`));
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}).on('error', reject);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Discover Chrome's browser-level WebSocket URL via the /json/version endpoint.
|
|
66
|
+
*/
|
|
67
|
+
export async function discoverBrowserWsUrl(port) {
|
|
68
|
+
const versionInfo = await cdpGet(`http://127.0.0.1:${port}/json/version`);
|
|
69
|
+
const targets = await cdpGet(`http://127.0.0.1:${port}/json/list`);
|
|
70
|
+
const tabCount = targets.filter(t => t.type === 'page').length;
|
|
71
|
+
return {
|
|
72
|
+
wsUrl: versionInfo.webSocketDebuggerUrl,
|
|
73
|
+
browser: versionInfo.Browser,
|
|
74
|
+
tabCount,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
// ---- CDP WebSocket session ----
|
|
78
|
+
/**
|
|
79
|
+
* Minimal CDP session over a single WebSocket.
|
|
80
|
+
* Supports browser-level commands and session-multiplexed target commands
|
|
81
|
+
* (via the sessionId parameter on send/events, using flatten: true).
|
|
82
|
+
*/
|
|
83
|
+
export class CDPSession {
|
|
84
|
+
wsUrl;
|
|
85
|
+
ws = null;
|
|
86
|
+
nextId = 1;
|
|
87
|
+
callbacks = new Map();
|
|
88
|
+
listeners = new Map();
|
|
89
|
+
constructor(wsUrl) {
|
|
90
|
+
this.wsUrl = wsUrl;
|
|
91
|
+
}
|
|
92
|
+
connect() {
|
|
93
|
+
return new Promise((resolve, reject) => {
|
|
94
|
+
this.ws = new WebSocket(this.wsUrl);
|
|
95
|
+
this.ws.onopen = () => resolve();
|
|
96
|
+
this.ws.onerror = (e) => reject(new Error(`CDP WebSocket error: ${e}`));
|
|
97
|
+
this.ws.onclose = () => {
|
|
98
|
+
// Reject all pending callbacks
|
|
99
|
+
for (const [, cb] of this.callbacks) {
|
|
100
|
+
clearTimeout(cb.timer);
|
|
101
|
+
cb.reject(new Error('CDP connection closed'));
|
|
102
|
+
}
|
|
103
|
+
this.callbacks.clear();
|
|
104
|
+
// Fire close listeners
|
|
105
|
+
for (const handler of this.listeners.get('close') ?? []) {
|
|
106
|
+
handler({});
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
this.ws.onmessage = (event) => {
|
|
110
|
+
const msg = JSON.parse(typeof event.data === 'string' ? event.data : String(event.data));
|
|
111
|
+
// Handle command responses
|
|
112
|
+
if (msg.id !== undefined && this.callbacks.has(msg.id)) {
|
|
113
|
+
const cb = this.callbacks.get(msg.id);
|
|
114
|
+
clearTimeout(cb.timer);
|
|
115
|
+
this.callbacks.delete(msg.id);
|
|
116
|
+
if (msg.error) {
|
|
117
|
+
const err = msg.error;
|
|
118
|
+
cb.reject(new Error(`CDP: ${err.message}`));
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
cb.resolve(msg.result);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Handle events
|
|
125
|
+
if (msg.method) {
|
|
126
|
+
const sessionId = msg.sessionId;
|
|
127
|
+
// Fire session-scoped handlers: "sessionId:Event.name"
|
|
128
|
+
if (sessionId) {
|
|
129
|
+
const scopedKey = `${sessionId}:${msg.method}`;
|
|
130
|
+
for (const handler of this.listeners.get(scopedKey) ?? []) {
|
|
131
|
+
handler(msg.params);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// Fire global handlers (non-session-scoped)
|
|
135
|
+
for (const handler of this.listeners.get(msg.method) ?? []) {
|
|
136
|
+
handler({
|
|
137
|
+
...msg.params,
|
|
138
|
+
...(sessionId ? { _sessionId: sessionId } : {}),
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
send(method, params = {}, sessionId) {
|
|
146
|
+
const id = this.nextId++;
|
|
147
|
+
return new Promise((resolve, reject) => {
|
|
148
|
+
const timer = setTimeout(() => {
|
|
149
|
+
this.callbacks.delete(id);
|
|
150
|
+
reject(new Error(`CDP timeout: ${method}`));
|
|
151
|
+
}, 15000);
|
|
152
|
+
this.callbacks.set(id, {
|
|
153
|
+
resolve: resolve,
|
|
154
|
+
reject,
|
|
155
|
+
timer,
|
|
156
|
+
});
|
|
157
|
+
const msg = { id, method, params };
|
|
158
|
+
if (sessionId)
|
|
159
|
+
msg.sessionId = sessionId;
|
|
160
|
+
this.ws.send(JSON.stringify(msg));
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
on(event, handler) {
|
|
164
|
+
if (!this.listeners.has(event))
|
|
165
|
+
this.listeners.set(event, []);
|
|
166
|
+
this.listeners.get(event).push(handler);
|
|
167
|
+
}
|
|
168
|
+
close() {
|
|
169
|
+
if (this.ws) {
|
|
170
|
+
this.ws.close();
|
|
171
|
+
this.ws = null;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Attach to a running Chrome instance via CDP, passively capture API traffic
|
|
177
|
+
* across all tabs, and generate signed skill files on SIGINT.
|
|
178
|
+
*/
|
|
179
|
+
export async function attach(options) {
|
|
180
|
+
const { port, domainPatterns, json } = options;
|
|
181
|
+
const log = (msg) => {
|
|
182
|
+
if (!json)
|
|
183
|
+
process.stderr.write(msg + '\n');
|
|
184
|
+
options.onProgress?.(msg);
|
|
185
|
+
};
|
|
186
|
+
// SIGINT state — registered before any connection attempt (spec requirement)
|
|
187
|
+
let stopping = false;
|
|
188
|
+
// Phase 0: Discover browser
|
|
189
|
+
let browserInfo;
|
|
190
|
+
try {
|
|
191
|
+
browserInfo = await discoverBrowserWsUrl(port);
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
log(`[attach] Cannot connect to Chrome on :${port}`);
|
|
195
|
+
log('');
|
|
196
|
+
log('To enable remote debugging, relaunch Chrome with:');
|
|
197
|
+
log(` google-chrome --remote-debugging-port=${port}`);
|
|
198
|
+
log('');
|
|
199
|
+
log('Or on macOS:');
|
|
200
|
+
log(` /Applications/Google\\ Chrome.app/Contents/MacOS/Google\\ Chrome --remote-debugging-port=${port}`);
|
|
201
|
+
process.exit(1);
|
|
202
|
+
}
|
|
203
|
+
log(`[attach] Connected to ${browserInfo.browser} on :${port} (${browserInfo.tabCount} tabs)`);
|
|
204
|
+
if (domainPatterns.length > 0) {
|
|
205
|
+
log(`[attach] Watching domains: ${domainPatterns.join(', ')}`);
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
log('[attach] Watching all domains');
|
|
209
|
+
}
|
|
210
|
+
// Phase 1: Connect browser-level CDP session
|
|
211
|
+
const browser = new CDPSession(browserInfo.wsUrl);
|
|
212
|
+
await browser.connect();
|
|
213
|
+
// Capture state
|
|
214
|
+
const generators = new Map();
|
|
215
|
+
const requests = new Map();
|
|
216
|
+
const responses = new Map();
|
|
217
|
+
let totalRequests = 0;
|
|
218
|
+
let filteredRequests = 0;
|
|
219
|
+
const startTime = Date.now();
|
|
220
|
+
const activeSessions = new Set();
|
|
221
|
+
const loggedSkippedDomains = new Set();
|
|
222
|
+
function enableNetworkForSession(sessionId) {
|
|
223
|
+
if (activeSessions.has(sessionId))
|
|
224
|
+
return;
|
|
225
|
+
activeSessions.add(sessionId);
|
|
226
|
+
// Prefix requestIds with sessionId to avoid collisions across tabs
|
|
227
|
+
const prefix = sessionId.slice(0, 8);
|
|
228
|
+
browser.on(`${sessionId}:Network.requestWillBeSent`, (params) => {
|
|
229
|
+
// Evict oldest entries if Maps grow too large (memory safety)
|
|
230
|
+
if (requests.size > 10000) {
|
|
231
|
+
const keys = [...requests.keys()].slice(0, 1000);
|
|
232
|
+
for (const k of keys) {
|
|
233
|
+
requests.delete(k);
|
|
234
|
+
responses.delete(k);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
const key = `${prefix}:${params.requestId}`;
|
|
238
|
+
const request = params.request;
|
|
239
|
+
requests.set(key, {
|
|
240
|
+
url: request.url,
|
|
241
|
+
method: request.method,
|
|
242
|
+
headers: request.headers,
|
|
243
|
+
postData: request.postData,
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
browser.on(`${sessionId}:Network.responseReceived`, (params) => {
|
|
247
|
+
const key = `${prefix}:${params.requestId}`;
|
|
248
|
+
const response = params.response;
|
|
249
|
+
responses.set(key, {
|
|
250
|
+
status: response.status,
|
|
251
|
+
headers: response.headers,
|
|
252
|
+
mimeType: response.mimeType,
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
browser.on(`${sessionId}:Network.loadingFinished`, (params) => {
|
|
256
|
+
const key = `${prefix}:${params.requestId}`;
|
|
257
|
+
const req = requests.get(key);
|
|
258
|
+
const resp = responses.get(key);
|
|
259
|
+
if (!req || !resp)
|
|
260
|
+
return;
|
|
261
|
+
totalRequests++;
|
|
262
|
+
// Get response body immediately (before Chrome evicts it from buffer).
|
|
263
|
+
// This MUST be called synchronously in the handler — deferring risks
|
|
264
|
+
// "No resource with given identifier found" on high-traffic tabs.
|
|
265
|
+
browser.send('Network.getResponseBody', { requestId: params.requestId }, sessionId).then((result) => {
|
|
266
|
+
processExchange(key, req, resp, result.body ?? '', log);
|
|
267
|
+
}).catch(() => {
|
|
268
|
+
// Body evicted or unavailable — still process exchange without body
|
|
269
|
+
processExchange(key, req, resp, '', log);
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
// Enable network capture for this session (fire-and-forget)
|
|
273
|
+
browser.send('Network.enable', {}, sessionId).catch(() => {
|
|
274
|
+
// Session may have been destroyed
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
function processExchange(key, req, resp, body, logFn) {
|
|
278
|
+
// Apply shouldCapture filter
|
|
279
|
+
if (!shouldCapture({ url: req.url, status: resp.status, contentType: resp.mimeType })) {
|
|
280
|
+
filteredRequests++;
|
|
281
|
+
if (req.url.startsWith('chrome-extension://')) {
|
|
282
|
+
logFn(` [skip] ${req.url.slice(0, 50)}... (extension)`);
|
|
283
|
+
}
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
// Apply domain glob filter
|
|
287
|
+
let hostname;
|
|
288
|
+
try {
|
|
289
|
+
hostname = new URL(req.url).hostname;
|
|
290
|
+
}
|
|
291
|
+
catch {
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
if (!matchesDomainGlob(hostname, domainPatterns)) {
|
|
295
|
+
filteredRequests++;
|
|
296
|
+
if (!loggedSkippedDomains.has(hostname)) {
|
|
297
|
+
loggedSkippedDomains.add(hostname);
|
|
298
|
+
logFn(` [skip] ${hostname} (not in domain filter)`);
|
|
299
|
+
}
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
// Get or create generator for this domain
|
|
303
|
+
if (!generators.has(hostname)) {
|
|
304
|
+
generators.set(hostname, new SkillGenerator());
|
|
305
|
+
}
|
|
306
|
+
const gen = generators.get(hostname);
|
|
307
|
+
const exchange = {
|
|
308
|
+
request: {
|
|
309
|
+
url: req.url,
|
|
310
|
+
method: req.method,
|
|
311
|
+
headers: req.headers,
|
|
312
|
+
postData: req.postData,
|
|
313
|
+
},
|
|
314
|
+
response: {
|
|
315
|
+
status: resp.status,
|
|
316
|
+
headers: resp.headers,
|
|
317
|
+
body,
|
|
318
|
+
contentType: resp.mimeType,
|
|
319
|
+
},
|
|
320
|
+
timestamp: new Date().toISOString(),
|
|
321
|
+
};
|
|
322
|
+
const endpoint = gen.addExchange(exchange);
|
|
323
|
+
if (endpoint) {
|
|
324
|
+
logFn(` [api] ${req.method} ${resp.status} ${hostname} ${endpoint.path}`);
|
|
325
|
+
}
|
|
326
|
+
// Clean up to avoid memory growth
|
|
327
|
+
requests.delete(key);
|
|
328
|
+
responses.delete(key);
|
|
329
|
+
}
|
|
330
|
+
// Phase 2: Attach to all existing page targets
|
|
331
|
+
const { targetInfos } = await browser.send('Target.getTargets');
|
|
332
|
+
for (const target of targetInfos) {
|
|
333
|
+
if (target.type === 'page') {
|
|
334
|
+
try {
|
|
335
|
+
const result = await browser.send('Target.attachToTarget', {
|
|
336
|
+
targetId: target.targetId,
|
|
337
|
+
flatten: true,
|
|
338
|
+
});
|
|
339
|
+
enableNetworkForSession(result.sessionId);
|
|
340
|
+
}
|
|
341
|
+
catch {
|
|
342
|
+
// Target may have navigated away
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
// Phase 3: Auto-attach to future targets (new tabs, popups, OAuth redirects).
|
|
347
|
+
// flatten: true is critical — uses session-based CDP multiplexing instead
|
|
348
|
+
// of legacy nested WebSocket connections.
|
|
349
|
+
browser.on('Target.attachedToTarget', (params) => {
|
|
350
|
+
const targetInfo = params.targetInfo;
|
|
351
|
+
if (targetInfo?.type === 'page') {
|
|
352
|
+
enableNetworkForSession(params.sessionId);
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
await browser.send('Target.setAutoAttach', {
|
|
356
|
+
autoAttach: true,
|
|
357
|
+
waitForDebuggerOnStart: false,
|
|
358
|
+
flatten: true,
|
|
359
|
+
});
|
|
360
|
+
// Phase 4: Wait for SIGINT or browser disconnect
|
|
361
|
+
const result = await new Promise((resolve) => {
|
|
362
|
+
const shutdown = async () => {
|
|
363
|
+
if (stopping) {
|
|
364
|
+
// Second SIGINT — force exit immediately
|
|
365
|
+
process.exit(1);
|
|
366
|
+
}
|
|
367
|
+
stopping = true;
|
|
368
|
+
log('');
|
|
369
|
+
const duration = Math.round((Date.now() - startTime) / 1000);
|
|
370
|
+
if (generators.size === 0) {
|
|
371
|
+
log('[attach] Nothing captured');
|
|
372
|
+
browser.close();
|
|
373
|
+
resolve({ domains: [], totalRequests, filteredRequests, duration });
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
log('[attach] Generating skill files...');
|
|
377
|
+
const machineId = await getMachineId();
|
|
378
|
+
const signingKey = deriveSigningKey(machineId);
|
|
379
|
+
const apitapDir = process.env.APITAP_DIR || join(homedir(), '.apitap');
|
|
380
|
+
const authManager = new AuthManager(apitapDir, machineId);
|
|
381
|
+
const domains = [];
|
|
382
|
+
for (const [domain, gen] of generators) {
|
|
383
|
+
let skill = gen.toSkillFile(domain);
|
|
384
|
+
if (skill.endpoints.length === 0)
|
|
385
|
+
continue;
|
|
386
|
+
// Store extracted auth credentials
|
|
387
|
+
const auth = deduplicateAuth(gen.getExtractedAuth());
|
|
388
|
+
if (auth) {
|
|
389
|
+
await authManager.store(domain, auth);
|
|
390
|
+
}
|
|
391
|
+
// Store OAuth credentials if detected
|
|
392
|
+
const oauthConfig = gen.getOAuthConfig();
|
|
393
|
+
if (oauthConfig) {
|
|
394
|
+
const clientSecret = gen.getOAuthClientSecret();
|
|
395
|
+
const refreshToken = gen.getOAuthRefreshToken();
|
|
396
|
+
if (clientSecret || refreshToken) {
|
|
397
|
+
await authManager.storeOAuthCredentials(domain, {
|
|
398
|
+
...(clientSecret ? { clientSecret } : {}),
|
|
399
|
+
...(refreshToken ? { refreshToken } : {}),
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
skill = signSkillFile(skill, signingKey);
|
|
404
|
+
const skillPath = await writeSkillFile(skill);
|
|
405
|
+
const displayPath = skillPath.replace(homedir(), '~');
|
|
406
|
+
const count = skill.endpoints.length;
|
|
407
|
+
log(` ${domain} — ${count} endpoint${count === 1 ? '' : 's'} → ${displayPath}`);
|
|
408
|
+
domains.push({ domain, endpoints: count, skillFile: displayPath });
|
|
409
|
+
}
|
|
410
|
+
browser.close();
|
|
411
|
+
resolve({ domains, totalRequests, filteredRequests, duration });
|
|
412
|
+
};
|
|
413
|
+
process.on('SIGINT', shutdown);
|
|
414
|
+
// Handle browser disconnect (user closed Chrome)
|
|
415
|
+
browser.on('close', () => {
|
|
416
|
+
if (!stopping)
|
|
417
|
+
shutdown();
|
|
418
|
+
});
|
|
419
|
+
});
|
|
420
|
+
return result;
|
|
421
|
+
}
|
|
422
|
+
//# sourceMappingURL=cdp-attach.js.map
|