session-bundle-kit 0.3.1__tar.gz

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.
Files changed (30) hide show
  1. session_bundle_kit-0.3.1/.github/workflows/ci.yml +30 -0
  2. session_bundle_kit-0.3.1/.github/workflows/release.yml +53 -0
  3. session_bundle_kit-0.3.1/.gitignore +12 -0
  4. session_bundle_kit-0.3.1/CHANGELOG.md +46 -0
  5. session_bundle_kit-0.3.1/LICENSE +21 -0
  6. session_bundle_kit-0.3.1/PKG-INFO +248 -0
  7. session_bundle_kit-0.3.1/README.md +213 -0
  8. session_bundle_kit-0.3.1/docs/AFFILIATE.md +58 -0
  9. session_bundle_kit-0.3.1/docs/FAQ.md +37 -0
  10. session_bundle_kit-0.3.1/pyproject.toml +81 -0
  11. session_bundle_kit-0.3.1/session_bundle_kit/__init__.py +20 -0
  12. session_bundle_kit-0.3.1/session_bundle_kit/bundle.py +123 -0
  13. session_bundle_kit-0.3.1/session_bundle_kit/cli.py +189 -0
  14. session_bundle_kit-0.3.1/session_bundle_kit/deal.py +25 -0
  15. session_bundle_kit-0.3.1/session_bundle_kit/diff.py +120 -0
  16. session_bundle_kit-0.3.1/session_bundle_kit/export.py +33 -0
  17. session_bundle_kit-0.3.1/session_bundle_kit/import_bundle.py +110 -0
  18. session_bundle_kit-0.3.1/session_bundle_kit/mlx.py +285 -0
  19. session_bundle_kit-0.3.1/session_bundle_kit/models.py +113 -0
  20. session_bundle_kit-0.3.1/session_bundle_kit/security.py +38 -0
  21. session_bundle_kit-0.3.1/tests/fixtures/state.json +25 -0
  22. session_bundle_kit-0.3.1/tests/fixtures/state_with_secret.json +24 -0
  23. session_bundle_kit-0.3.1/tests/test_bundle.py +34 -0
  24. session_bundle_kit-0.3.1/tests/test_cli.py +63 -0
  25. session_bundle_kit-0.3.1/tests/test_diff.py +47 -0
  26. session_bundle_kit-0.3.1/tests/test_import.py +25 -0
  27. session_bundle_kit-0.3.1/tests/test_mlx.py +198 -0
  28. session_bundle_kit-0.3.1/tests/test_mlx_cli.py +78 -0
  29. session_bundle_kit-0.3.1/tests/test_roundtrip.py +34 -0
  30. session_bundle_kit-0.3.1/tests/test_security.py +25 -0
@@ -0,0 +1,30 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+
6
+ jobs:
7
+ test:
8
+ runs-on: ubuntu-latest
9
+ strategy:
10
+ fail-fast: false
11
+ matrix:
12
+ python-version: ["3.10", "3.11", "3.12"]
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - name: Set up Python ${{ matrix.python-version }}
17
+ uses: actions/setup-python@v5
18
+ with:
19
+ python-version: ${{ matrix.python-version }}
20
+
21
+ - name: Install package and dev deps
22
+ run: |
23
+ python -m pip install --upgrade pip
24
+ pip install -e ".[dev]"
25
+
26
+ - name: Ruff
27
+ run: ruff check .
28
+
29
+ - name: Pytest
30
+ run: pytest
@@ -0,0 +1,53 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+
14
+ - name: Set up Python 3.12
15
+ uses: actions/setup-python@v5
16
+ with:
17
+ python-version: "3.12"
18
+
19
+ - name: Install package and dev deps
20
+ run: |
21
+ python -m pip install --upgrade pip
22
+ pip install -e ".[dev]"
23
+
24
+ - name: Ruff
25
+ run: ruff check .
26
+
27
+ - name: Pytest
28
+ run: pytest
29
+
30
+ publish:
31
+ needs: test
32
+ runs-on: ubuntu-latest
33
+ steps:
34
+ - uses: actions/checkout@v4
35
+
36
+ - name: Set up Python 3.12
37
+ uses: actions/setup-python@v5
38
+ with:
39
+ python-version: "3.12"
40
+
41
+ - name: Install build tools
42
+ run: python -m pip install --upgrade pip build twine
43
+
44
+ - name: Build
45
+ run: python -m build
46
+
47
+ - name: Twine check
48
+ run: twine check dist/*
49
+
50
+ - name: Publish to PyPI
51
+ uses: pypa/gh-action-pypi-publish@release/v1
52
+ with:
53
+ password: ${{ secrets.PYPI_API_TOKEN }}
@@ -0,0 +1,12 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *$py.class
4
+ *.egg-info/
5
+ .eggs/
6
+ dist/
7
+ build/
8
+ .pytest_cache/
9
+ .ruff_cache/
10
+ .venv/
11
+ venv/
12
+ .env
@@ -0,0 +1,46 @@
1
+ # Changelog
2
+
3
+ ## v0.3.1 — 2026-06-11
4
+
5
+ ### Changed
6
+
7
+ - PyPI README: SEO subtitle (Playwright session export), session migration playbook, contextual affiliate note
8
+ - `pyproject.toml`: storage_state / MLX cookie keywords (`playwright-storage-state`, `multilogin-cookies`)
9
+ - `--show-deal`: contextual session-restore copy with affiliate disclosure
10
+ - FAQ: +4 SEO questions (zip backup, MLX import, importer pairing, affiliate opt-in)
11
+
12
+ ## v0.3.0 — 2026-06-11
13
+
14
+ ### Added
15
+
16
+ - `session-bundle mlx-pull --profile-id UUID -o bundle.zip` — MLX cookie export → session-bundle-v1
17
+ - `session-bundle mlx-push --dry-run` — validate bundle without Launcher/Cloud API calls
18
+ - `MlxBundleClient.pull_bundle()` / `push_bundle(dry_run=)` with MLX↔Playwright cookie mapping
19
+ - Handles MLX export `cookies` as JSON array or quoted JSON string
20
+ - Mock API tests for pull, push, dry-run, export errors, and CLI
21
+
22
+ ### Changed
23
+
24
+ - `MlxBundlePusher` is an alias for `MlxBundleClient`
25
+ - README: MLX pull/push flow and cdp-connect-kit cross-link
26
+
27
+ ## v0.2.0 — 2026-06-11
28
+
29
+ ### Added
30
+
31
+ - Bundle spec **v1**: `manifest.json` with `spec: session-bundle-v1` and `version` field
32
+ - `diff` reports cookie **domains** added / removed / changed
33
+ - `import --dry-run` validates without writing (default; explicit flag documented)
34
+ - Security warnings for plaintext passwords/secrets in `localStorage` / `sessionStorage`
35
+ - Roundtrip test: export fixture → import dry-run
36
+ - README: "When Chrome user-data-dir fails in 2026" (Chrome 136+ policy)
37
+ - GitHub Actions CI (Python 3.10–3.12)
38
+
39
+ ### Changed
40
+
41
+ - `ImportReport` includes `warnings` separate from blocking `issues`
42
+ - Manifest read requires `version` field
43
+
44
+ ## v0.1.0 — 2026-06-01
45
+
46
+ - Initial release: export/import/diff bundles, optional MLX cookie push
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 session-bundle-kit contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,248 @@
1
+ Metadata-Version: 2.4
2
+ Name: session-bundle-kit
3
+ Version: 0.3.1
4
+ Summary: Playwright storage_state zip export — backup sessions, diff bundles, MLX cookie pull/push. CLI: session-bundle.
5
+ Project-URL: Homepage, https://github.com/session-bundle-kit/session-bundle-kit
6
+ Project-URL: Documentation, https://github.com/session-bundle-kit/session-bundle-kit#readme
7
+ Project-URL: Repository, https://github.com/session-bundle-kit/session-bundle-kit
8
+ Project-URL: Issues, https://github.com/session-bundle-kit/session-bundle-kit/issues
9
+ Author: session-bundle-kit contributors
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: browser-backup,browser-session-migration,chrome-136,context-backup,cookie-export,indexeddb-manifest,localstorage-backup,multilogin-cookies,playwright-storage-state,portable-session,session-bundle,session-diff,session-export,session-restore,storage-state,zip-export
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Environment :: Console
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Internet :: WWW/HTTP :: Browsers
23
+ Classifier: Topic :: Software Development :: Quality Assurance
24
+ Classifier: Typing :: Typed
25
+ Requires-Python: >=3.10
26
+ Requires-Dist: click>=8.1
27
+ Provides-Extra: dev
28
+ Requires-Dist: httpx>=0.27; extra == 'dev'
29
+ Requires-Dist: pytest-httpx>=0.34; extra == 'dev'
30
+ Requires-Dist: pytest>=8.0; extra == 'dev'
31
+ Requires-Dist: ruff>=0.8; extra == 'dev'
32
+ Provides-Extra: mlx
33
+ Requires-Dist: httpx>=0.27; extra == 'mlx'
34
+ Description-Content-Type: text/markdown
35
+
36
+ # session-bundle-kit
37
+
38
+ **Playwright session export & backup** — zip storage_state cookies and localStorage; MLX cookie pull/push for profile migration.
39
+
40
+ [![PyPI version](https://img.shields.io/pypi/v/session-bundle-kit.svg)](https://pypi.org/project/session-bundle-kit/)
41
+ [![Python versions](https://img.shields.io/pypi/pyversions/session-bundle-kit.svg)](https://pypi.org/project/session-bundle-kit/)
42
+ [![License: MIT](https://img.shields.io/pypi/l/session-bundle-kit.svg)](https://pypi.org/project/session-bundle-kit/)
43
+
44
+ ```bash
45
+ pip install session-bundle-kit
46
+ session-bundle export state.json -o bundle.zip
47
+ ```
48
+
49
+ CLI: **`session-bundle`** · Python **3.10+** · optional **`[mlx]`** for Launcher helpers
50
+
51
+ **Playwright session export & backup** — zip `storage_state` cookies and localStorage; MLX cookie pull/push for profile migration.
52
+
53
+ Export and compare **browser session bundles** — cookies, `localStorage`, `sessionStorage`, and IndexedDB metadata — from Playwright storage state JSON.
54
+
55
+ Pure Python zip format. Optional MLX push for cookie import into antidetect profiles.
56
+
57
+ ## Problem
58
+
59
+ Playwright `storage_state.json` is a single file mixing cookies and per-origin storage. Teams need:
60
+
61
+ - Portable **zip bundles** with a manifest for CI and backups
62
+ - **Dry-run validation** before restoring sessions
63
+ - **Diff** between two session snapshots
64
+ - Push cookies into **MLX profiles** after export
65
+
66
+ ## Install
67
+
68
+ ```bash
69
+ pip install session-bundle-kit
70
+ ```
71
+
72
+ MLX profile push:
73
+
74
+ ```bash
75
+ pip install session-bundle-kit[mlx]
76
+ ```
77
+
78
+ ## Quick start
79
+
80
+ ```bash
81
+ # Export Playwright storage state -> bundle zip
82
+ session-bundle export --playwright-context ./state.json -o bundle.zip
83
+
84
+ # Validate bundle (dry-run default)
85
+ session-bundle import bundle.zip --dry-run
86
+
87
+ # Compare two bundles
88
+ session-bundle diff bundle_a.zip bundle_b.zip
89
+ ```
90
+
91
+ ## Bundle format (spec v1)
92
+
93
+ ```
94
+ bundle.zip
95
+ ├── manifest.json # spec, version, counts, source
96
+ ├── cookies.json # Playwright cookie list
97
+ ├── origins/
98
+ │ └── https%3A%2F%2Fexample.com.json # localStorage + sessionStorage
99
+ └── indexeddb/
100
+ └── metadata.json # IDB database names/versions (metadata only)
101
+ ```
102
+
103
+ IndexedDB **metadata** is included for audit/diff; full IDB binary export is out of scope.
104
+
105
+ `manifest.json` example:
106
+
107
+ ```json
108
+ {
109
+ "spec": "session-bundle-v1",
110
+ "version": 1,
111
+ "source": "playwright-storage-state",
112
+ "cookie_count": 12,
113
+ "origin_count": 3,
114
+ "indexeddb_count": 0
115
+ }
116
+ ```
117
+
118
+ ## CLI
119
+
120
+ | Command | Description |
121
+ |---------|-------------|
122
+ | `session-bundle export --playwright-context FILE -o OUT.zip` | Create bundle from Playwright state |
123
+ | `session-bundle import FILE --dry-run` | Validate bundle without writing (default) |
124
+ | `session-bundle diff A.zip B.zip` | Cookie domain + storage/IDB diff |
125
+ | `session-bundle mlx-pull --profile-id UUID -o bundle.zip` | Export MLX profile cookies → bundle (`[mlx]`) |
126
+ | `session-bundle mlx-push --profile-id UUID --bundle FILE` | Import bundle cookies to MLX (`[mlx]`) |
127
+ | `session-bundle mlx-push ... --dry-run` | Validate bundle; no MLX API calls |
128
+
129
+ ## API
130
+
131
+ ```python
132
+ from session_bundle_kit import export_playwright_context, validate_bundle, diff_bundles
133
+
134
+ export_playwright_context("state.json", "bundle.zip")
135
+ report = validate_bundle("bundle.zip")
136
+ diff = diff_bundles("old.zip", "new.zip")
137
+ ```
138
+
139
+ Restore to Playwright:
140
+
141
+ ```python
142
+ from session_bundle_kit.bundle import SessionBundle
143
+
144
+ bundle = SessionBundle.read_zip("bundle.zip")
145
+ context = await browser.new_context(storage_state=bundle.to_playwright_storage_state())
146
+ ```
147
+
148
+ ## MLX pull / push (`[mlx]` extra)
149
+
150
+ Round-trip **cookies** between MLX profiles and neutral **session-bundle-v1** zips. Storage/IDB in bundles from Playwright export are manifest-only on push; MLX Launcher APIs move cookies only.
151
+
152
+ **Pull** (profile → zip):
153
+
154
+ 1. `GET api.multilogin.com/profile/unlock?profile_ids=UUID`
155
+ 2. `POST launcher.mlx.yt:45001/api/v1/cookies/export`
156
+
157
+ **Push** (zip → profile):
158
+
159
+ 1. Validate bundle (`--dry-run` stops here)
160
+ 2. `GET api.multilogin.com/profile/unlock?profile_ids=UUID`
161
+ 3. `POST launcher.mlx.yt:45001/api/v1/cookies/import`
162
+
163
+ ```bash
164
+ export MLX_TOKEN="..."
165
+
166
+ # Export MLX profile session to portable bundle
167
+ session-bundle mlx-pull --profile-id PROFILE_UUID -o bundle.zip
168
+
169
+ # Validate before import
170
+ session-bundle mlx-push --profile-id PROFILE_UUID --bundle bundle.zip --dry-run
171
+
172
+ # Import cookies into target profile
173
+ session-bundle mlx-push --profile-id PROFILE_UUID --bundle bundle.zip
174
+ ```
175
+
176
+ Peer pattern for Launcher lifecycle: see `cdp-connect-kit` MLX integration docs.
177
+
178
+ ## When login sessions break after profile switch (playbook)
179
+
180
+ Sites re-challenge when cookies land on a **new fingerprint or IP**. Use bundles to move **stored** credentials deliberately — not as a bypass.
181
+
182
+ | Symptom | Likely cause | Next step |
183
+ |---------|--------------|-----------|
184
+ | Import ok, still logged out | Domain/subdomain mismatch, expired cookies | `session-bundle diff` old vs new; fix with [cookie-jar-bridge](https://pypi.org/project/cookie-jar-bridge/) |
185
+ | Step-up / CAPTCHA after restore | IP or fingerprint drift | Match proxy lane; probe with [playwright-cdp-probe](https://pypi.org/project/playwright-cdp-probe/) |
186
+ | MLX push succeeds, site fails | Cookies only — no `localStorage` on target | Restore storage via Playwright `storage_state` on same profile |
187
+ | Migration metadata only | `antidetect-importer` left `_cookies` sidecar | `mlx-pull` source → edit → `mlx-push --dry-run` → push |
188
+
189
+ **Session migration pipeline:**
190
+
191
+ ```bash
192
+ session-bundle export --playwright-context state.json -o bundle.zip
193
+ session-bundle import bundle.zip --dry-run
194
+ session-bundle mlx-push --profile-id TARGET_UUID --bundle bundle.zip --dry-run
195
+ export MLX_TOKEN=...
196
+ session-bundle mlx-push --profile-id TARGET_UUID --bundle bundle.zip
197
+ cdp-probe mlx --profile-id TARGET_UUID --url https://your-app.example # verify session + exposure
198
+ ```
199
+
200
+ Treat bundle zips as **secrets** — same sensitivity as password files.
201
+
202
+ ## When Chrome `user-data-dir` fails in 2026
203
+
204
+ Starting with **Chrome 136** (March 2025), Google changed how remote debugging works on the default profile. Per the [Chrome Developers blog](https://developer.chrome.com/blog/remote-debugging-port):
205
+
206
+ - `--remote-debugging-port` and `--remote-debugging-pipe` are **ignored** when targeting Chrome's **default** user data directory.
207
+ - You must pass a **custom** `--user-data-dir` pointing to a non-default profile path for CDP to bind.
208
+ - The change targets cookie theft via remote debugging after [App-Bound Encryption](https://developer.chrome.com/blog/app-bound-encryption); Chrome for Testing still supports the older automation workflow.
209
+
210
+ **Practical impact:** copying your daily `Default` profile and launching with `--remote-debugging-port` no longer works on stock Chrome 136+. Session-bundle-kit sidesteps this by exporting **Playwright `storage_state.json`** (cookies + origin storage) into portable zips — restore via `new_context(storage_state=...)` on antidetect or isolated profiles instead of attaching CDP to your real Chrome profile.
211
+
212
+ Enterprise admins can still control remote debugging via the [Allow remote debugging](https://support.google.com/chrome/a/answer/2657289) Chrome policy on managed devices.
213
+
214
+ ## Limitations
215
+
216
+ - **No live IDB export** — IndexedDB section is metadata manifest only.
217
+ - **sessionStorage** preserved in bundle format but Playwright native export may omit it; include in custom state JSON if needed.
218
+ - **mlx-push** imports cookies only; storage must be restored via Playwright or profile sync separately.
219
+ - **Secrets** — bundles contain session secrets; treat zip files as credentials. Import warns on likely plaintext passwords in web storage.
220
+
221
+ ## Production
222
+
223
+ Export sessions to portable zips, validate with `mlx-push --dry-run`, then import cookies into MLX profiles after `antidetect-importer` migration or failed login on a new profile.
224
+
225
+ **Partner note (affiliate):** When restoring sessions into **isolated Multilogin X** profiles (not shared Chrome `user-data-dir`), Launcher cookie import pairs with profile-level proxy and fingerprint. Eligible new browser purchases may accept code **`SAAS50`** at [multilogin.com](https://multilogin.com/?ref=SAAS50) — verify terms before checkout. Export/diff/validate work without MLX. Full disclosure: [docs/AFFILIATE.md](docs/AFFILIATE.md). Coupon details only via `session-bundle --show-deal` (never printed by default).
226
+
227
+ **FAQ:** [docs/FAQ.md](docs/FAQ.md) — Playwright storage_state export, Chrome 136 CDP, MLX cookie import.
228
+
229
+
230
+ ## Related tools (on PyPI)
231
+
232
+ | Package | CLI | Role |
233
+ |---------|-----|------|
234
+ | [playwright-cdp-probe](https://pypi.org/project/playwright-cdp-probe/) | `cdp-probe` | CDP / WebDriver exposure score |
235
+ | [cookie-jar-bridge](https://pypi.org/project/cookie-jar-bridge/) | `cookie-bridge` | Netscape ↔ Playwright cookies |
236
+ | [proxy-lane-checker](https://pypi.org/project/proxy-lane-checker/) | `proxy-lane` | Proxy TCP / HTTP / geo / DNSBL |
237
+ | [fingerprint-coherence](https://pypi.org/project/fingerprint-coherence/) | `fp-coherence` | UA / screen / timezone lint |
238
+
239
+ **Toolkit pipeline:** `proxy-lane check` → `fp-coherence audit` → automate → `cdp-probe run` → `cookie-bridge validate`
240
+
241
+ ## License
242
+
243
+ MIT
244
+
245
+ ---
246
+
247
+ **Production antidetect:** [Multilogin X](https://multilogin.com/?ref=SAAS50) · Code `SAAS50` (-50% browser) · `MIN50` (-50% cloud phone)
248
+ More scripts: [@Multilogin_Scripts_Bot](https://t.me/Multilogin_Scripts_Bot) · [Coupons](https://anti-detect.github.io/)
@@ -0,0 +1,213 @@
1
+ # session-bundle-kit
2
+
3
+ **Playwright session export & backup** — zip storage_state cookies and localStorage; MLX cookie pull/push for profile migration.
4
+
5
+ [![PyPI version](https://img.shields.io/pypi/v/session-bundle-kit.svg)](https://pypi.org/project/session-bundle-kit/)
6
+ [![Python versions](https://img.shields.io/pypi/pyversions/session-bundle-kit.svg)](https://pypi.org/project/session-bundle-kit/)
7
+ [![License: MIT](https://img.shields.io/pypi/l/session-bundle-kit.svg)](https://pypi.org/project/session-bundle-kit/)
8
+
9
+ ```bash
10
+ pip install session-bundle-kit
11
+ session-bundle export state.json -o bundle.zip
12
+ ```
13
+
14
+ CLI: **`session-bundle`** · Python **3.10+** · optional **`[mlx]`** for Launcher helpers
15
+
16
+ **Playwright session export & backup** — zip `storage_state` cookies and localStorage; MLX cookie pull/push for profile migration.
17
+
18
+ Export and compare **browser session bundles** — cookies, `localStorage`, `sessionStorage`, and IndexedDB metadata — from Playwright storage state JSON.
19
+
20
+ Pure Python zip format. Optional MLX push for cookie import into antidetect profiles.
21
+
22
+ ## Problem
23
+
24
+ Playwright `storage_state.json` is a single file mixing cookies and per-origin storage. Teams need:
25
+
26
+ - Portable **zip bundles** with a manifest for CI and backups
27
+ - **Dry-run validation** before restoring sessions
28
+ - **Diff** between two session snapshots
29
+ - Push cookies into **MLX profiles** after export
30
+
31
+ ## Install
32
+
33
+ ```bash
34
+ pip install session-bundle-kit
35
+ ```
36
+
37
+ MLX profile push:
38
+
39
+ ```bash
40
+ pip install session-bundle-kit[mlx]
41
+ ```
42
+
43
+ ## Quick start
44
+
45
+ ```bash
46
+ # Export Playwright storage state -> bundle zip
47
+ session-bundle export --playwright-context ./state.json -o bundle.zip
48
+
49
+ # Validate bundle (dry-run default)
50
+ session-bundle import bundle.zip --dry-run
51
+
52
+ # Compare two bundles
53
+ session-bundle diff bundle_a.zip bundle_b.zip
54
+ ```
55
+
56
+ ## Bundle format (spec v1)
57
+
58
+ ```
59
+ bundle.zip
60
+ ├── manifest.json # spec, version, counts, source
61
+ ├── cookies.json # Playwright cookie list
62
+ ├── origins/
63
+ │ └── https%3A%2F%2Fexample.com.json # localStorage + sessionStorage
64
+ └── indexeddb/
65
+ └── metadata.json # IDB database names/versions (metadata only)
66
+ ```
67
+
68
+ IndexedDB **metadata** is included for audit/diff; full IDB binary export is out of scope.
69
+
70
+ `manifest.json` example:
71
+
72
+ ```json
73
+ {
74
+ "spec": "session-bundle-v1",
75
+ "version": 1,
76
+ "source": "playwright-storage-state",
77
+ "cookie_count": 12,
78
+ "origin_count": 3,
79
+ "indexeddb_count": 0
80
+ }
81
+ ```
82
+
83
+ ## CLI
84
+
85
+ | Command | Description |
86
+ |---------|-------------|
87
+ | `session-bundle export --playwright-context FILE -o OUT.zip` | Create bundle from Playwright state |
88
+ | `session-bundle import FILE --dry-run` | Validate bundle without writing (default) |
89
+ | `session-bundle diff A.zip B.zip` | Cookie domain + storage/IDB diff |
90
+ | `session-bundle mlx-pull --profile-id UUID -o bundle.zip` | Export MLX profile cookies → bundle (`[mlx]`) |
91
+ | `session-bundle mlx-push --profile-id UUID --bundle FILE` | Import bundle cookies to MLX (`[mlx]`) |
92
+ | `session-bundle mlx-push ... --dry-run` | Validate bundle; no MLX API calls |
93
+
94
+ ## API
95
+
96
+ ```python
97
+ from session_bundle_kit import export_playwright_context, validate_bundle, diff_bundles
98
+
99
+ export_playwright_context("state.json", "bundle.zip")
100
+ report = validate_bundle("bundle.zip")
101
+ diff = diff_bundles("old.zip", "new.zip")
102
+ ```
103
+
104
+ Restore to Playwright:
105
+
106
+ ```python
107
+ from session_bundle_kit.bundle import SessionBundle
108
+
109
+ bundle = SessionBundle.read_zip("bundle.zip")
110
+ context = await browser.new_context(storage_state=bundle.to_playwright_storage_state())
111
+ ```
112
+
113
+ ## MLX pull / push (`[mlx]` extra)
114
+
115
+ Round-trip **cookies** between MLX profiles and neutral **session-bundle-v1** zips. Storage/IDB in bundles from Playwright export are manifest-only on push; MLX Launcher APIs move cookies only.
116
+
117
+ **Pull** (profile → zip):
118
+
119
+ 1. `GET api.multilogin.com/profile/unlock?profile_ids=UUID`
120
+ 2. `POST launcher.mlx.yt:45001/api/v1/cookies/export`
121
+
122
+ **Push** (zip → profile):
123
+
124
+ 1. Validate bundle (`--dry-run` stops here)
125
+ 2. `GET api.multilogin.com/profile/unlock?profile_ids=UUID`
126
+ 3. `POST launcher.mlx.yt:45001/api/v1/cookies/import`
127
+
128
+ ```bash
129
+ export MLX_TOKEN="..."
130
+
131
+ # Export MLX profile session to portable bundle
132
+ session-bundle mlx-pull --profile-id PROFILE_UUID -o bundle.zip
133
+
134
+ # Validate before import
135
+ session-bundle mlx-push --profile-id PROFILE_UUID --bundle bundle.zip --dry-run
136
+
137
+ # Import cookies into target profile
138
+ session-bundle mlx-push --profile-id PROFILE_UUID --bundle bundle.zip
139
+ ```
140
+
141
+ Peer pattern for Launcher lifecycle: see `cdp-connect-kit` MLX integration docs.
142
+
143
+ ## When login sessions break after profile switch (playbook)
144
+
145
+ Sites re-challenge when cookies land on a **new fingerprint or IP**. Use bundles to move **stored** credentials deliberately — not as a bypass.
146
+
147
+ | Symptom | Likely cause | Next step |
148
+ |---------|--------------|-----------|
149
+ | Import ok, still logged out | Domain/subdomain mismatch, expired cookies | `session-bundle diff` old vs new; fix with [cookie-jar-bridge](https://pypi.org/project/cookie-jar-bridge/) |
150
+ | Step-up / CAPTCHA after restore | IP or fingerprint drift | Match proxy lane; probe with [playwright-cdp-probe](https://pypi.org/project/playwright-cdp-probe/) |
151
+ | MLX push succeeds, site fails | Cookies only — no `localStorage` on target | Restore storage via Playwright `storage_state` on same profile |
152
+ | Migration metadata only | `antidetect-importer` left `_cookies` sidecar | `mlx-pull` source → edit → `mlx-push --dry-run` → push |
153
+
154
+ **Session migration pipeline:**
155
+
156
+ ```bash
157
+ session-bundle export --playwright-context state.json -o bundle.zip
158
+ session-bundle import bundle.zip --dry-run
159
+ session-bundle mlx-push --profile-id TARGET_UUID --bundle bundle.zip --dry-run
160
+ export MLX_TOKEN=...
161
+ session-bundle mlx-push --profile-id TARGET_UUID --bundle bundle.zip
162
+ cdp-probe mlx --profile-id TARGET_UUID --url https://your-app.example # verify session + exposure
163
+ ```
164
+
165
+ Treat bundle zips as **secrets** — same sensitivity as password files.
166
+
167
+ ## When Chrome `user-data-dir` fails in 2026
168
+
169
+ Starting with **Chrome 136** (March 2025), Google changed how remote debugging works on the default profile. Per the [Chrome Developers blog](https://developer.chrome.com/blog/remote-debugging-port):
170
+
171
+ - `--remote-debugging-port` and `--remote-debugging-pipe` are **ignored** when targeting Chrome's **default** user data directory.
172
+ - You must pass a **custom** `--user-data-dir` pointing to a non-default profile path for CDP to bind.
173
+ - The change targets cookie theft via remote debugging after [App-Bound Encryption](https://developer.chrome.com/blog/app-bound-encryption); Chrome for Testing still supports the older automation workflow.
174
+
175
+ **Practical impact:** copying your daily `Default` profile and launching with `--remote-debugging-port` no longer works on stock Chrome 136+. Session-bundle-kit sidesteps this by exporting **Playwright `storage_state.json`** (cookies + origin storage) into portable zips — restore via `new_context(storage_state=...)` on antidetect or isolated profiles instead of attaching CDP to your real Chrome profile.
176
+
177
+ Enterprise admins can still control remote debugging via the [Allow remote debugging](https://support.google.com/chrome/a/answer/2657289) Chrome policy on managed devices.
178
+
179
+ ## Limitations
180
+
181
+ - **No live IDB export** — IndexedDB section is metadata manifest only.
182
+ - **sessionStorage** preserved in bundle format but Playwright native export may omit it; include in custom state JSON if needed.
183
+ - **mlx-push** imports cookies only; storage must be restored via Playwright or profile sync separately.
184
+ - **Secrets** — bundles contain session secrets; treat zip files as credentials. Import warns on likely plaintext passwords in web storage.
185
+
186
+ ## Production
187
+
188
+ Export sessions to portable zips, validate with `mlx-push --dry-run`, then import cookies into MLX profiles after `antidetect-importer` migration or failed login on a new profile.
189
+
190
+ **Partner note (affiliate):** When restoring sessions into **isolated Multilogin X** profiles (not shared Chrome `user-data-dir`), Launcher cookie import pairs with profile-level proxy and fingerprint. Eligible new browser purchases may accept code **`SAAS50`** at [multilogin.com](https://multilogin.com/?ref=SAAS50) — verify terms before checkout. Export/diff/validate work without MLX. Full disclosure: [docs/AFFILIATE.md](docs/AFFILIATE.md). Coupon details only via `session-bundle --show-deal` (never printed by default).
191
+
192
+ **FAQ:** [docs/FAQ.md](docs/FAQ.md) — Playwright storage_state export, Chrome 136 CDP, MLX cookie import.
193
+
194
+
195
+ ## Related tools (on PyPI)
196
+
197
+ | Package | CLI | Role |
198
+ |---------|-----|------|
199
+ | [playwright-cdp-probe](https://pypi.org/project/playwright-cdp-probe/) | `cdp-probe` | CDP / WebDriver exposure score |
200
+ | [cookie-jar-bridge](https://pypi.org/project/cookie-jar-bridge/) | `cookie-bridge` | Netscape ↔ Playwright cookies |
201
+ | [proxy-lane-checker](https://pypi.org/project/proxy-lane-checker/) | `proxy-lane` | Proxy TCP / HTTP / geo / DNSBL |
202
+ | [fingerprint-coherence](https://pypi.org/project/fingerprint-coherence/) | `fp-coherence` | UA / screen / timezone lint |
203
+
204
+ **Toolkit pipeline:** `proxy-lane check` → `fp-coherence audit` → automate → `cdp-probe run` → `cookie-bridge validate`
205
+
206
+ ## License
207
+
208
+ MIT
209
+
210
+ ---
211
+
212
+ **Production antidetect:** [Multilogin X](https://multilogin.com/?ref=SAAS50) · Code `SAAS50` (-50% browser) · `MIN50` (-50% cloud phone)
213
+ More scripts: [@Multilogin_Scripts_Bot](https://t.me/Multilogin_Scripts_Bot) · [Coupons](https://anti-detect.github.io/)