deja-browser 0.1.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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 deja-browser authors
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,244 @@
1
+ Metadata-Version: 2.4
2
+ Name: deja-browser
3
+ Version: 0.1.1
4
+ Summary: The agent browser that remembers: a separate Chromium profile your AI agent drives over CDP, with site recipes so the second visit skips reading the page.
5
+ License-Expression: MIT
6
+ Project-URL: Homepage, https://github.com/drpwchen/deja-browser
7
+ Project-URL: Changelog, https://github.com/drpwchen/deja-browser/blob/main/CHANGELOG.md
8
+ Project-URL: Issues, https://github.com/drpwchen/deja-browser/issues
9
+ Keywords: browser-automation,cdp,ai-agent,claude-code,playwright,captcha
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Operating System :: Microsoft :: Windows
14
+ Classifier: Operating System :: MacOS
15
+ Classifier: Operating System :: POSIX :: Linux
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Topic :: Internet :: WWW/HTTP :: Browsers
18
+ Requires-Python: >=3.11
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: playwright>=1.45
22
+ Provides-Extra: stealth
23
+ Requires-Dist: patchright; extra == "stealth"
24
+ Provides-Extra: keyring
25
+ Requires-Dist: keyring; extra == "keyring"
26
+ Provides-Extra: audio
27
+ Requires-Dist: faster-whisper; extra == "audio"
28
+ Requires-Dist: av<19; extra == "audio"
29
+ Provides-Extra: ocr
30
+ Requires-Dist: ddddocr; extra == "ocr"
31
+ Provides-Extra: dev
32
+ Requires-Dist: pytest; extra == "dev"
33
+ Dynamic: license-file
34
+
35
+ # deja-browser
36
+
37
+ *The agent browser that remembers.* (Formerly edge-recipes.)
38
+
39
+ **A browser for your AI agent that is not your browser.** A separate Chromium profile your agent
40
+ drives over CDP — with no telemetry, no extension in your everyday browser, and site *recipes*
41
+ so the second visit to a site does not need to read the page at all.
42
+
43
+ Works with any agent that can run shell commands (Claude Code, Codex CLI, Gemini CLI, Cursor,
44
+ Aider, …) and from plain Python.
45
+
46
+ > **Let your agent install it.** Tell it: *"Read
47
+ > https://github.com/drpwchen/deja-browser/blob/main/AGENTS.md and set this up with me."* It will
48
+ > ask you the few choices that matter, have you log in to your sites by hand, and run a smoke test.
49
+
50
+ > **Status: early release (0.1).** Tested on Windows 11 (Edge), macOS on Apple Silicon (Chrome)
51
+ > and Linux (headless Chromium, in the egress test). Feedback and recipes-in-the-wild welcome.
52
+
53
+ ## Why
54
+
55
+ Browser-extension bridges for agents put an extension with full debugger access into the browser
56
+ where you are logged in to everything, and some of them phone home with no way to turn it off.
57
+ Browsers have also stopped letting you fence such extensions away from chosen sites. deja-browser
58
+ takes the other route:
59
+
60
+ - **Separation instead of a block list.** The agent gets its own profile. You log in there only to
61
+ the sites it should use. Your mail, bank and broker are simply not logged in.
62
+ - **No telemetry, tested.** The tool makes no outbound connection of its own.
63
+ [`tests/egress/run.sh`](tests/egress/run.sh) runs every action and a full recipe cycle inside a
64
+ network namespace with only loopback, traces every `connect()` of the tool's processes, and
65
+ fails on anything that is not `127.0.0.1` (its `SELFTEST=1` mode proves the check catches a
66
+ deliberate connection). The only outbound features are ones you switch on: ntfy notifications
67
+ and the opt-in hCaptcha solver.
68
+ - **No passwords in the browser.** On launch the profile's password, card and address autofill is
69
+ turned off, and a password-manager extension installed in it triggers a warning. Secrets the
70
+ agent may use stay in your OS keyring or password-manager CLI and are only named in recipes.
71
+ - **Cheap to read.** Snapshots can be cut to one subtree, to interactive elements, or to lines
72
+ matching a word; screenshots and PDFs come back as file paths, never as inline images.
73
+ - **Learn once, replay.** The first visit finds the JSON endpoint or the form; the recipe replays
74
+ it later, outside the browser when cookies are enough.
75
+
76
+ ## What it does
77
+
78
+ - **Dedicated browser profile.** Drives any Chromium browser (Edge, Chrome, Chromium, Brave —
79
+ auto-detected) over CDP on `127.0.0.1` only, with its own user-data dir. Your everyday browser
80
+ profile is never touched. Kimi-WebBridge-compatible action names and return shapes, so scripts
81
+ written for that bridge port over.
82
+ - **Named sessions.** Every task names a session; its tabs are tracked across processes and
83
+ `close_session` closes only those.
84
+ - **API discovery.** `network_capture` records the requests one action triggers (bodies to files,
85
+ credential headers redacted) — the raw material for a recipe.
86
+ - **Recipes with a tier ladder** (cheapest first, falls through on failure, records what worked):
87
+ - `http` — plain HTTP outside the browser, with cookies read live from the browser (never stored)
88
+ - `page` — `fetch()` inside a tab on the site (native cookies, Cloudflare clearance, CSRF)
89
+ - `script` — the recipe's own JavaScript in the page (DOM read / form fill)
90
+ - **Shape checks.** Every response is compared with the JSON shape recorded at verify time; a
91
+ mismatch is reported as *stale*, never returned as data.
92
+ - **Write guard.** Recipes with side effects (`"writes": true`) only run with `--allow-write`.
93
+ - **Secrets by name.** Recipes reference `{secret:NAME}`; values are resolved in-process and are
94
+ never printed or returned, and never typed into a refused host.
95
+ - **CAPTCHA gate.** Waits for Turnstile / Cloudflare to clear, then tries one trusted checkbox
96
+ click. Local solvers (reCAPTCHA audio via `faster-whisper`, text CAPTCHAs via `ddddocr`) run only
97
+ if you install those extras; the hCaptcha solver only if you enable it. Otherwise it notifies you.
98
+ - **Guard rails.** `navigate` and recipes refuse mail, account sign-in, banking, brokerage and
99
+ payment hosts (built-in list, extendable); recipes also refuse ticketing / rail-booking hosts by
100
+ default. These stop accidents, not attackers — see *Safety model*.
101
+
102
+ ## Options at a glance
103
+
104
+ | | Options | Notes |
105
+ |---|---|---|
106
+ | OS | Windows, macOS, Linux | Linux tested headless only |
107
+ | Browser | Edge, Chrome, Chromium, Brave, any Chromium (`[browser] executable`) | no Firefox / Safari (no CDP) |
108
+ | Driver | `patchright` (extra `stealth`, used when installed), `playwright` | patchright passes more bot checks |
109
+ | Secrets | `keyring` (default), `command`, `env`, `python` | `command` runs 1Password `op`, Bitwarden `bw`, macOS `security`, `pass`, … |
110
+ | Notifications | ntfy URL, any command, stderr (default) | for "a human is needed" |
111
+ | CAPTCHA extras | `audio` (local), `ocr` (local), hCaptcha solver (cloud, opt-in) | none installed by default |
112
+ | Agents | anything with a shell; Agent Skills folder in `skills/deja-browser/` | Python API: `from deja_browser.browser import wb` |
113
+
114
+ ## Safety model
115
+
116
+ What protects you is **separation**: the agent profile is never logged in to mail, banking or
117
+ brokerage, and stores no passwords. The refused-host list is a guard rail: it stops an agent from
118
+ navigating there by mistake and keeps stored secrets from being typed into those sites, but a page
119
+ script can still redirect the tab, and an agent with shell access can edit your config. Treat it
120
+ as a seat belt, not a lock.
121
+
122
+ Password managers: do not install their extension in the agent profile — while unlocked it can
123
+ fill any saved password for whatever is driving the page. To let the agent log in to a few
124
+ low-risk sites by itself, give it a dedicated vault through the password manager's CLI
125
+ (`[secrets] backend = "command"`, see `config.example.toml`). 1Password service accounts can be
126
+ limited to one vault; an unlocked Bitwarden CLI can read the whole vault.
127
+
128
+ Two things no tool can change: the browser vendor's own services (e.g. Safe Browsing / SmartScreen
129
+ URL checks) still apply to the agent profile, and whatever page content your agent reads goes to
130
+ its model provider. Keep sensitive pages (health records, personal data) out of agent sessions.
131
+
132
+ ## Install
133
+
134
+ Requires Python ≥ 3.11 and a Chromium-based browser.
135
+
136
+ ```sh
137
+ pip install "deja-browser[stealth,keyring]" # recommended: patchright driver + OS keyring secrets
138
+ pip install "deja-browser[audio,ocr]" # reCAPTCHA audio (faster-whisper), text CAPTCHAs (ddddocr)
139
+ pip install -e ".[dev]" # from a clone: core + pytest
140
+ python -m playwright install-deps # Linux only, if system libraries are missing
141
+ ```
142
+
143
+ `deja-browser` uses your installed browser; it does not need `playwright install`.
144
+
145
+ ## Quick start
146
+
147
+ ```sh
148
+ deja-cdp launch # start the dedicated browser; log in to sites by hand if needed
149
+ deja-cdp navigate '{"url": "https://example.com"}' --session demo
150
+ deja-cdp evaluate '{"code": "document.title"}' --session demo
151
+ deja-cdp close_session '{}' --session demo
152
+
153
+ deja-browser verify draft.json '{"q": "rust"}' # try every tier, print shape + preview
154
+ deja-browser save draft.json # only after a passing verify of this draft
155
+ deja-browser run hn.algolia.com/search '{"q": "rust"}'
156
+ deja-browser list
157
+ deja-browser gate https://example.com/login # open a URL, clear any challenge, report
158
+ ```
159
+
160
+ From Python:
161
+
162
+ ```python
163
+ from deja_browser.browser import wb
164
+ wb("navigate", {"url": "https://example.com"}, session="task")
165
+ wb("snapshot", {"max_chars": 4000}, session="task")
166
+ wb("close_session", {}, session="task")
167
+ ```
168
+
169
+ `deja-cdp --help` and `deja-browser --help` list every action and the full recipe format.
170
+
171
+ ## Recipe format (abridged)
172
+
173
+ ```json
174
+ {
175
+ "version": 1,
176
+ "name": "search",
177
+ "description": "Hacker News full-text search (example)",
178
+ "entry_url": "https://hn.algolia.com/",
179
+ "params": [{"name": "q", "required": true}],
180
+ "request": {"method": "GET", "url": "https://hn.algolia.com/api/v1/search?query={q}"},
181
+ "pick": {"path": "hits", "fields": ["title", "url"], "limit": 20},
182
+ "writes": false
183
+ }
184
+ ```
185
+
186
+ No recipes ship with the package — you (or your agent) build them per site. Recipes are stored as `<recipes dir>/<host>/<name>.json` and addressed as `<host>/<name>`.
187
+
188
+ ## Configuration
189
+
190
+ Optional. Copy `config.example.toml` to:
191
+
192
+ | OS | Path |
193
+ |---|---|
194
+ | Windows | `%APPDATA%\deja-browser\config.toml` |
195
+ | macOS | `~/Library/Application Support/deja-browser/config.toml` |
196
+ | Linux | `~/.config/deja-browser/config.toml` |
197
+
198
+ or point `DEJA_BROWSER_CONFIG` at a file. It covers the browser executable and profile, the
199
+ recipes directory, extra denied hosts, the secret backend (`keyring` / `env` / `python`), and
200
+ notifications (an ntfy URL or any command; default is stderr).
201
+
202
+ ## hCaptcha solver (opt-in, cloud)
203
+
204
+ Off by default. When enabled, the CAPTCHA gate hands hCaptcha to
205
+ [hcaptcha-challenger](https://github.com/QIN2DIM/hcaptcha-challenger), which asks Google Gemini to
206
+ answer the challenge. **This sends the cropped challenge image to Google** under your own API key
207
+ (not the page, not cookies). hcaptcha-challenger is GPL-3.0 and is not bundled — install it
208
+ yourself:
209
+
210
+ ```sh
211
+ pip install "hcaptcha-challenger @ git+https://github.com/QIN2DIM/hcaptcha-challenger@28ee79b"
212
+ keyring set deja-browser GEMINI_API_KEY # or your configured secret backend
213
+ ```
214
+
215
+ ```toml
216
+ [captcha]
217
+ hcaptcha_solver = "gemini"
218
+ ```
219
+
220
+ Best effort: on the public demo the "drag the missing item into the grid" type passed 13/15, the
221
+ hexagon shape-matching type 1/5 (small samples). Failures fall through to the human step.
222
+
223
+ ## Acceptable use
224
+
225
+ This is a personal automation tool for sites and accounts you are entitled to use. Respect each
226
+ site's terms of service and rate limits. Do not use it for ticket scalping, mass account
227
+ creation, credential stuffing, or to defeat protections on systems you do not own. Ticket and
228
+ rail-booking sites are refused by default: several jurisdictions criminalise automated ticket
229
+ purchase (e.g. Taiwan's Railway Act art. 65). `[recipes] allow_ticket_hosts` can lift that; we
230
+ recommend you don't, and the decision and its consequences are yours. The project
231
+ does not integrate paid CAPTCHA-solving services and will not.
232
+
233
+ ## Tests
234
+
235
+ ```sh
236
+ python -m pytest -q # pure functions; no browser, no network
237
+ sudo PY=$(which python) tests/egress/run.sh # Linux: no outbound connection (needs strace)
238
+ sudo PY=$(which python) SELFTEST=1 tests/egress/run.sh # must FAIL: proves the check catches one
239
+ ```
240
+
241
+ ## License
242
+
243
+ MIT — see `LICENSE`. Optional dependencies keep their own licenses; GPL-licensed packages are
244
+ never vendored into this repository.
@@ -0,0 +1,210 @@
1
+ # deja-browser
2
+
3
+ *The agent browser that remembers.* (Formerly edge-recipes.)
4
+
5
+ **A browser for your AI agent that is not your browser.** A separate Chromium profile your agent
6
+ drives over CDP — with no telemetry, no extension in your everyday browser, and site *recipes*
7
+ so the second visit to a site does not need to read the page at all.
8
+
9
+ Works with any agent that can run shell commands (Claude Code, Codex CLI, Gemini CLI, Cursor,
10
+ Aider, …) and from plain Python.
11
+
12
+ > **Let your agent install it.** Tell it: *"Read
13
+ > https://github.com/drpwchen/deja-browser/blob/main/AGENTS.md and set this up with me."* It will
14
+ > ask you the few choices that matter, have you log in to your sites by hand, and run a smoke test.
15
+
16
+ > **Status: early release (0.1).** Tested on Windows 11 (Edge), macOS on Apple Silicon (Chrome)
17
+ > and Linux (headless Chromium, in the egress test). Feedback and recipes-in-the-wild welcome.
18
+
19
+ ## Why
20
+
21
+ Browser-extension bridges for agents put an extension with full debugger access into the browser
22
+ where you are logged in to everything, and some of them phone home with no way to turn it off.
23
+ Browsers have also stopped letting you fence such extensions away from chosen sites. deja-browser
24
+ takes the other route:
25
+
26
+ - **Separation instead of a block list.** The agent gets its own profile. You log in there only to
27
+ the sites it should use. Your mail, bank and broker are simply not logged in.
28
+ - **No telemetry, tested.** The tool makes no outbound connection of its own.
29
+ [`tests/egress/run.sh`](tests/egress/run.sh) runs every action and a full recipe cycle inside a
30
+ network namespace with only loopback, traces every `connect()` of the tool's processes, and
31
+ fails on anything that is not `127.0.0.1` (its `SELFTEST=1` mode proves the check catches a
32
+ deliberate connection). The only outbound features are ones you switch on: ntfy notifications
33
+ and the opt-in hCaptcha solver.
34
+ - **No passwords in the browser.** On launch the profile's password, card and address autofill is
35
+ turned off, and a password-manager extension installed in it triggers a warning. Secrets the
36
+ agent may use stay in your OS keyring or password-manager CLI and are only named in recipes.
37
+ - **Cheap to read.** Snapshots can be cut to one subtree, to interactive elements, or to lines
38
+ matching a word; screenshots and PDFs come back as file paths, never as inline images.
39
+ - **Learn once, replay.** The first visit finds the JSON endpoint or the form; the recipe replays
40
+ it later, outside the browser when cookies are enough.
41
+
42
+ ## What it does
43
+
44
+ - **Dedicated browser profile.** Drives any Chromium browser (Edge, Chrome, Chromium, Brave —
45
+ auto-detected) over CDP on `127.0.0.1` only, with its own user-data dir. Your everyday browser
46
+ profile is never touched. Kimi-WebBridge-compatible action names and return shapes, so scripts
47
+ written for that bridge port over.
48
+ - **Named sessions.** Every task names a session; its tabs are tracked across processes and
49
+ `close_session` closes only those.
50
+ - **API discovery.** `network_capture` records the requests one action triggers (bodies to files,
51
+ credential headers redacted) — the raw material for a recipe.
52
+ - **Recipes with a tier ladder** (cheapest first, falls through on failure, records what worked):
53
+ - `http` — plain HTTP outside the browser, with cookies read live from the browser (never stored)
54
+ - `page` — `fetch()` inside a tab on the site (native cookies, Cloudflare clearance, CSRF)
55
+ - `script` — the recipe's own JavaScript in the page (DOM read / form fill)
56
+ - **Shape checks.** Every response is compared with the JSON shape recorded at verify time; a
57
+ mismatch is reported as *stale*, never returned as data.
58
+ - **Write guard.** Recipes with side effects (`"writes": true`) only run with `--allow-write`.
59
+ - **Secrets by name.** Recipes reference `{secret:NAME}`; values are resolved in-process and are
60
+ never printed or returned, and never typed into a refused host.
61
+ - **CAPTCHA gate.** Waits for Turnstile / Cloudflare to clear, then tries one trusted checkbox
62
+ click. Local solvers (reCAPTCHA audio via `faster-whisper`, text CAPTCHAs via `ddddocr`) run only
63
+ if you install those extras; the hCaptcha solver only if you enable it. Otherwise it notifies you.
64
+ - **Guard rails.** `navigate` and recipes refuse mail, account sign-in, banking, brokerage and
65
+ payment hosts (built-in list, extendable); recipes also refuse ticketing / rail-booking hosts by
66
+ default. These stop accidents, not attackers — see *Safety model*.
67
+
68
+ ## Options at a glance
69
+
70
+ | | Options | Notes |
71
+ |---|---|---|
72
+ | OS | Windows, macOS, Linux | Linux tested headless only |
73
+ | Browser | Edge, Chrome, Chromium, Brave, any Chromium (`[browser] executable`) | no Firefox / Safari (no CDP) |
74
+ | Driver | `patchright` (extra `stealth`, used when installed), `playwright` | patchright passes more bot checks |
75
+ | Secrets | `keyring` (default), `command`, `env`, `python` | `command` runs 1Password `op`, Bitwarden `bw`, macOS `security`, `pass`, … |
76
+ | Notifications | ntfy URL, any command, stderr (default) | for "a human is needed" |
77
+ | CAPTCHA extras | `audio` (local), `ocr` (local), hCaptcha solver (cloud, opt-in) | none installed by default |
78
+ | Agents | anything with a shell; Agent Skills folder in `skills/deja-browser/` | Python API: `from deja_browser.browser import wb` |
79
+
80
+ ## Safety model
81
+
82
+ What protects you is **separation**: the agent profile is never logged in to mail, banking or
83
+ brokerage, and stores no passwords. The refused-host list is a guard rail: it stops an agent from
84
+ navigating there by mistake and keeps stored secrets from being typed into those sites, but a page
85
+ script can still redirect the tab, and an agent with shell access can edit your config. Treat it
86
+ as a seat belt, not a lock.
87
+
88
+ Password managers: do not install their extension in the agent profile — while unlocked it can
89
+ fill any saved password for whatever is driving the page. To let the agent log in to a few
90
+ low-risk sites by itself, give it a dedicated vault through the password manager's CLI
91
+ (`[secrets] backend = "command"`, see `config.example.toml`). 1Password service accounts can be
92
+ limited to one vault; an unlocked Bitwarden CLI can read the whole vault.
93
+
94
+ Two things no tool can change: the browser vendor's own services (e.g. Safe Browsing / SmartScreen
95
+ URL checks) still apply to the agent profile, and whatever page content your agent reads goes to
96
+ its model provider. Keep sensitive pages (health records, personal data) out of agent sessions.
97
+
98
+ ## Install
99
+
100
+ Requires Python ≥ 3.11 and a Chromium-based browser.
101
+
102
+ ```sh
103
+ pip install "deja-browser[stealth,keyring]" # recommended: patchright driver + OS keyring secrets
104
+ pip install "deja-browser[audio,ocr]" # reCAPTCHA audio (faster-whisper), text CAPTCHAs (ddddocr)
105
+ pip install -e ".[dev]" # from a clone: core + pytest
106
+ python -m playwright install-deps # Linux only, if system libraries are missing
107
+ ```
108
+
109
+ `deja-browser` uses your installed browser; it does not need `playwright install`.
110
+
111
+ ## Quick start
112
+
113
+ ```sh
114
+ deja-cdp launch # start the dedicated browser; log in to sites by hand if needed
115
+ deja-cdp navigate '{"url": "https://example.com"}' --session demo
116
+ deja-cdp evaluate '{"code": "document.title"}' --session demo
117
+ deja-cdp close_session '{}' --session demo
118
+
119
+ deja-browser verify draft.json '{"q": "rust"}' # try every tier, print shape + preview
120
+ deja-browser save draft.json # only after a passing verify of this draft
121
+ deja-browser run hn.algolia.com/search '{"q": "rust"}'
122
+ deja-browser list
123
+ deja-browser gate https://example.com/login # open a URL, clear any challenge, report
124
+ ```
125
+
126
+ From Python:
127
+
128
+ ```python
129
+ from deja_browser.browser import wb
130
+ wb("navigate", {"url": "https://example.com"}, session="task")
131
+ wb("snapshot", {"max_chars": 4000}, session="task")
132
+ wb("close_session", {}, session="task")
133
+ ```
134
+
135
+ `deja-cdp --help` and `deja-browser --help` list every action and the full recipe format.
136
+
137
+ ## Recipe format (abridged)
138
+
139
+ ```json
140
+ {
141
+ "version": 1,
142
+ "name": "search",
143
+ "description": "Hacker News full-text search (example)",
144
+ "entry_url": "https://hn.algolia.com/",
145
+ "params": [{"name": "q", "required": true}],
146
+ "request": {"method": "GET", "url": "https://hn.algolia.com/api/v1/search?query={q}"},
147
+ "pick": {"path": "hits", "fields": ["title", "url"], "limit": 20},
148
+ "writes": false
149
+ }
150
+ ```
151
+
152
+ No recipes ship with the package — you (or your agent) build them per site. Recipes are stored as `<recipes dir>/<host>/<name>.json` and addressed as `<host>/<name>`.
153
+
154
+ ## Configuration
155
+
156
+ Optional. Copy `config.example.toml` to:
157
+
158
+ | OS | Path |
159
+ |---|---|
160
+ | Windows | `%APPDATA%\deja-browser\config.toml` |
161
+ | macOS | `~/Library/Application Support/deja-browser/config.toml` |
162
+ | Linux | `~/.config/deja-browser/config.toml` |
163
+
164
+ or point `DEJA_BROWSER_CONFIG` at a file. It covers the browser executable and profile, the
165
+ recipes directory, extra denied hosts, the secret backend (`keyring` / `env` / `python`), and
166
+ notifications (an ntfy URL or any command; default is stderr).
167
+
168
+ ## hCaptcha solver (opt-in, cloud)
169
+
170
+ Off by default. When enabled, the CAPTCHA gate hands hCaptcha to
171
+ [hcaptcha-challenger](https://github.com/QIN2DIM/hcaptcha-challenger), which asks Google Gemini to
172
+ answer the challenge. **This sends the cropped challenge image to Google** under your own API key
173
+ (not the page, not cookies). hcaptcha-challenger is GPL-3.0 and is not bundled — install it
174
+ yourself:
175
+
176
+ ```sh
177
+ pip install "hcaptcha-challenger @ git+https://github.com/QIN2DIM/hcaptcha-challenger@28ee79b"
178
+ keyring set deja-browser GEMINI_API_KEY # or your configured secret backend
179
+ ```
180
+
181
+ ```toml
182
+ [captcha]
183
+ hcaptcha_solver = "gemini"
184
+ ```
185
+
186
+ Best effort: on the public demo the "drag the missing item into the grid" type passed 13/15, the
187
+ hexagon shape-matching type 1/5 (small samples). Failures fall through to the human step.
188
+
189
+ ## Acceptable use
190
+
191
+ This is a personal automation tool for sites and accounts you are entitled to use. Respect each
192
+ site's terms of service and rate limits. Do not use it for ticket scalping, mass account
193
+ creation, credential stuffing, or to defeat protections on systems you do not own. Ticket and
194
+ rail-booking sites are refused by default: several jurisdictions criminalise automated ticket
195
+ purchase (e.g. Taiwan's Railway Act art. 65). `[recipes] allow_ticket_hosts` can lift that; we
196
+ recommend you don't, and the decision and its consequences are yours. The project
197
+ does not integrate paid CAPTCHA-solving services and will not.
198
+
199
+ ## Tests
200
+
201
+ ```sh
202
+ python -m pytest -q # pure functions; no browser, no network
203
+ sudo PY=$(which python) tests/egress/run.sh # Linux: no outbound connection (needs strace)
204
+ sudo PY=$(which python) SELFTEST=1 tests/egress/run.sh # must FAIL: proves the check catches one
205
+ ```
206
+
207
+ ## License
208
+
209
+ MIT — see `LICENSE`. Optional dependencies keep their own licenses; GPL-licensed packages are
210
+ never vendored into this repository.
@@ -0,0 +1,49 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "deja-browser"
7
+ version = "0.1.1"
8
+ description = "The agent browser that remembers: a separate Chromium profile your AI agent drives over CDP, with site recipes so the second visit skips reading the page."
9
+ readme = "README.md"
10
+ keywords = ["browser-automation", "cdp", "ai-agent", "claude-code", "playwright", "captcha"]
11
+ classifiers = [
12
+ "Development Status :: 3 - Alpha",
13
+ "Environment :: Console",
14
+ "Intended Audience :: Developers",
15
+ "Operating System :: Microsoft :: Windows",
16
+ "Operating System :: MacOS",
17
+ "Operating System :: POSIX :: Linux",
18
+ "Programming Language :: Python :: 3",
19
+ "Topic :: Internet :: WWW/HTTP :: Browsers",
20
+ ]
21
+ license = "MIT"
22
+ requires-python = ">=3.11"
23
+ dependencies = ["playwright>=1.45"]
24
+
25
+ [project.urls]
26
+ Homepage = "https://github.com/drpwchen/deja-browser"
27
+ Changelog = "https://github.com/drpwchen/deja-browser/blob/main/CHANGELOG.md"
28
+ Issues = "https://github.com/drpwchen/deja-browser/issues"
29
+
30
+ [project.optional-dependencies]
31
+ stealth = ["patchright"] # default driver when installed (hides Runtime.enable)
32
+ keyring = ["keyring"] # default secret backend
33
+ audio = ["faster-whisper", "av<19"] # reCAPTCHA audio; faster-whisper 1.2.1 passes av.open(metadata_errors=), removed in av 19
34
+ ocr = ["ddddocr"] # text-image CAPTCHAs
35
+ # hCaptcha (GPL-3.0, optional, installed by the user). PyPI 0.19.0 fails the drag challenges;
36
+ # the tested build is git 28ee79b. Not installable from PyPI as an extra until upstream releases.
37
+ # pip install "hcaptcha-challenger @ git+https://github.com/QIN2DIM/hcaptcha-challenger@28ee79b"
38
+ dev = ["pytest"]
39
+
40
+ [project.scripts]
41
+ deja-browser = "deja_browser.recipe:main"
42
+ deja-cdp = "deja_browser.browser:main"
43
+
44
+ [tool.setuptools.packages.find]
45
+ where = ["src"]
46
+
47
+ [tool.pytest.ini_options]
48
+ testpaths = ["tests"]
49
+ pythonpath = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,2 @@
1
+ """deja-browser: learn a site's data path once in a real browser, replay it without reading the page."""
2
+ __version__ = "0.1.1"