jev-cdp 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Browser Use
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.
package/NOTICE.md ADDED
@@ -0,0 +1,9 @@
1
+ # Attribution
2
+
3
+ Jev CDP is a TypeScript and Bun port of [browser-use/jev-ultrafast](https://github.com/browser-use/jev-ultrafast), originally published by Browser Use under the MIT License.
4
+
5
+ The port began from upstream commit [`452c1ad2dd628008f1d5608f28158d76e49e6cc0`](https://github.com/browser-use/jev-ultrafast/commit/452c1ad2dd628008f1d5608f28158d76e49e6cc0). The original copyright and MIT license are preserved in `LICENSE`.
6
+
7
+ The observed-element snapshot policy, speculative TypeSafe operation/target choice design, stale-page guards, bounded action loop, and text-helper separation are derived from that source. This port replaces the Python runtime and Browser Harness Python client with Bun, TypeScript, and a small direct Chrome DevTools Protocol client. It also makes the action limit, foreground tab, and retained-tab behavior configurable.
8
+
9
+ TypeSafe and Jev are products of [TypeSafe AI](https://typesafe.ai/). This project is an independent port and is not an official Browser Use or TypeSafe AI project.
package/README.md ADDED
@@ -0,0 +1,198 @@
1
+ # Jev CDP
2
+
3
+ Jev CDP is a small Jev-powered bridge to Chrome through the Chrome DevTools Protocol (CDP). The deliberately narrow name describes what this project owns: it connects Jev's typed browser decisions to a Chrome CDP session. It is not intended to be a general browser-use framework or an official Jev client.
4
+
5
+ It is a Bun and TypeScript port of [Browser Use's `jev-ultrafast`](https://github.com/browser-use/jev-ultrafast). Jev chooses one browser operation and one observed target at a time. An authenticated Codex CLI running `gpt-5.6-luna` generates text only when Jev selects a text field.
6
+
7
+ This is an early experimental port. See [NOTICE.md](NOTICE.md) for source attribution and the exact upstream revision.
8
+
9
+ ## What is preserved
10
+
11
+ - One TypeSafe request per decision cycle, with speculative target heads.
12
+ - Model choices are limited to operations and indexed elements observed by code.
13
+ - Actual DOM nodes are retained in the page and checked again before input.
14
+ - Text generation is isolated from browser execution and must return `{ "text": string }`.
15
+ - A stale decision cannot execute against a changed page.
16
+ - Every run has a configurable maximum browser-step budget.
17
+
18
+ ## Requirements
19
+
20
+ - [Bun](https://bun.sh/)
21
+ - Google Chrome running with a local CDP endpoint
22
+ - A TypeSafe API key
23
+ - An authenticated Codex CLI for the default Luna text helper
24
+
25
+ ## Setup
26
+
27
+ Run the published CLI without adding it to a project. Bun must be installed for either command:
28
+
29
+ ```bash
30
+ bunx jev-cdp@0.1.2 help run
31
+ npx -y jev-cdp@0.1.2 help run
32
+ ```
33
+
34
+ Chrome with a CDP endpoint and `TYPESAFE_API_KEY` are required for browser runs. FFmpeg is required for `--recording`.
35
+
36
+ For source development:
37
+
38
+ ```bash
39
+ bun install
40
+ cp .env.example .env
41
+ ```
42
+
43
+ Keep `TYPESAFE_API_KEY` out of `.env` when possible. On macOS, inject it from Keychain when launching the runner.
44
+
45
+ Start an isolated Chrome instance:
46
+
47
+ ```bash
48
+ open -na "Google Chrome" --args \
49
+ --remote-debugging-port=9222 \
50
+ --user-data-dir=/tmp/jev-cdp-chrome
51
+ ```
52
+
53
+ Check the complete local setup:
54
+
55
+ ```bash
56
+ TYPESAFE_API_KEY="$(security find-generic-password -a "$USER" -s 'ai.typesafe.api-key' -w)" \
57
+ bun run run -- doctor
58
+ ```
59
+
60
+ Explore the CLI without credentials or a browser connection:
61
+
62
+ ```bash
63
+ bun run run -- --help
64
+ bun run run -- help run
65
+ bun run run -- --version
66
+ ```
67
+
68
+ ## Run the verified todo scenario
69
+
70
+ The repository includes and serves its own isolated todo fixture. This command runs three fresh scenarios, verifies each stage in code, runs a separate two-step budget-stop check, and writes screenshots, JSON traces, and MP4 recordings under the ignored `artifacts/` directory:
71
+
72
+ ```bash
73
+ TYPESAFE_API_KEY="$(security find-generic-password -a "$USER" -s 'ai.typesafe.api-key' -w)" \
74
+ bun run scenario:todo -- --runs 3 --max-steps 6 --guard-steps 2 --visible
75
+ ```
76
+
77
+ The scenario deliberately uses small, literal goals: add one item, click its completion control, then click the Completed filter. Deterministic page-state checks stop each successful stage before Jev can repeat it. If Jev incorrectly reports `DONE`, the orchestrator rejects that claim and can retry the attached tab with a more explicit bounded goal. The scenario exits with code `0` only when every clean-run assertion passes and the guard run stops exactly at its configured action budget.
78
+
79
+ FFmpeg must be on `PATH` to render the recordings. The Codex subscription helper reports latency and model identity, but its CLI integration does not expose token usage.
80
+
81
+ ## Run one ad hoc goal
82
+
83
+ The lower-level CLI exits with code `0` only when Jev reports `DONE`. `BLOCKED` and step-budget exhaustion use nonzero exit codes and leave a structured summary in the terminal.
84
+
85
+ ```bash
86
+ TYPESAFE_API_KEY="$(security find-generic-password -a "$USER" -s 'ai.typesafe.api-key' -w)" \
87
+ bun run run -- run \
88
+ --url https://example.com \
89
+ --goal 'Open the More information link.' \
90
+ --max-steps 4 \
91
+ --visible \
92
+ --keep-open \
93
+ --interaction-pauses 500 \
94
+ --recording artifacts/example/run.mp4 \
95
+ --screenshot artifacts/example/final.jpg \
96
+ --final-state
97
+ ```
98
+
99
+ `--recording` captures Chrome's compositor screencast stream for the full goal and renders an H.264 MP4. Because Chrome's native pointer is not part of that stream, the adapter draws a high-contrast cursor that starts at the viewport center, glides to each target, and pulses on clicks. `--interaction-pauses` adds a deterministic delay in milliseconds after moving to a click target and before pressing the mouse; Jev does not choose or observe this delay. `--screenshot` saves the final viewport after the goal stops; when recording is also enabled, it reuses the final screencast frame.
100
+
101
+ `--final-state` adds an AI-oriented semantic snapshot to the final JSON on standard output. It includes the final URL, title, visible text, viewport, scroll state, actionable elements, accessible labels, and control state such as `pressed`, `checked`, `selected`, and `expanded`. Progress remains on standard error, so a coding agent can parse standard output as one JSON object and choose the next bounded goal without another browser observation.
102
+
103
+ ## Supply known field values without another LLM
104
+
105
+ For portable QA scenarios, let the planner provide exact test data instead of invoking the Luna fallback. Match a field by its observed accessible label:
106
+
107
+ ```bash
108
+ TYPESAFE_API_KEY="$(security find-generic-password -a "$USER" -s 'ai.typesafe.api-key' -w)" \
109
+ bun run run -- run \
110
+ --url http://127.0.0.1:4173 \
111
+ --goal 'Add exactly one todo named Dodge. Finish when it is visible.' \
112
+ --field-value 'New todo=Dodge' \
113
+ --max-steps 4 \
114
+ --keep-open \
115
+ --final-state
116
+ ```
117
+
118
+ The exact value is typed with zero text-helper latency. If no matching `--field-value` is supplied, the configured Luna or API helper remains the fallback. Keep repeated work as separate verified goals: add one named item, verify it, then continue on the returned `targetId`. This avoids a compound goal repeatedly filling the same field.
119
+
120
+ For passwords or other secrets, pass the name of an existing environment variable so the value does not appear in the process arguments:
121
+
122
+ ```bash
123
+ bun run run -- run \
124
+ --url https://example.test/login \
125
+ --goal 'Log in with the caller-provided Username and Password.' \
126
+ --field-value 'Username=Admin' \
127
+ --field-value-env 'Password=TEST_LOGIN_PASSWORD' \
128
+ --max-steps 6 \
129
+ --final-state
130
+ ```
131
+
132
+ Password controls are exposed to Jev as writable fields, but their values are represented only as empty or `[set]`. Sensitive values are redacted from semantic state, model requests, action history, and text-call records. If Jev selects a sensitive field without a caller-provided value, execution stops instead of asking the text helper to invent one.
133
+
134
+ ## Use an already-open Chrome tab
135
+
136
+ List the controllable page targets:
137
+
138
+ ```bash
139
+ bun run run -- tabs
140
+ ```
141
+
142
+ Then attach to one exact target without navigating it:
143
+
144
+ ```bash
145
+ TYPESAFE_API_KEY="$(security find-generic-password -a "$USER" -s 'ai.typesafe.api-key' -w)" \
146
+ bun run run -- run \
147
+ --tab TARGET_ID_FROM_LIST \
148
+ --goal 'Complete all the todos and show the completed list.' \
149
+ --max-steps 12 \
150
+ --visible
151
+ ```
152
+
153
+ An attached tab is never closed by the runner. Add `--url` only when you intentionally want to navigate that selected tab before the run.
154
+
155
+ ## Use a fresh browser context
156
+
157
+ Omitting `--tab` creates a new tab in Chrome's existing default context, so it shares that profile's cookies and local storage. Add `--fresh-context` when the run needs a clean, isolated session:
158
+
159
+ ```bash
160
+ TYPESAFE_API_KEY="$(security find-generic-password -a "$USER" -s 'ai.typesafe.api-key' -w)" \
161
+ bun run run -- run \
162
+ --fresh-context \
163
+ --url https://example.test/login \
164
+ --goal 'Inspect the logged-out page and finish.' \
165
+ --max-steps 2 \
166
+ --visible \
167
+ --final-state
168
+ ```
169
+
170
+ The context is disposed after evidence capture by default. Combine it with `--keep-open` to retain the isolated window and use the returned `targetId` in later runs. `--fresh-context` cannot be combined with `--tab`.
171
+
172
+ ## Configuration
173
+
174
+ | CLI | Environment | Default | Purpose |
175
+ | --- | --- | --- | --- |
176
+ | `--max-steps N` | `JEV_MAX_STEPS` | `12` | Maximum executed browser actions |
177
+ | `--visible` | `JEV_BROWSER_VISIBLE=1` | off | Activate the controlled Chrome tab |
178
+ | `--keep-open` | `JEV_BROWSER_KEEP_OPEN=1` | off | Leave the controlled tab open after the run |
179
+ | `--fresh-context` | `JEV_BROWSER_FRESH_CONTEXT=1` | off | Create an isolated context with fresh cookies and storage |
180
+ | `--cdp URL` | `CHROME_CDP_URL` | `http://127.0.0.1:9222` | Chrome DevTools HTTP endpoint |
181
+ | `--tab TARGET_ID` | — | create a new tab | Attach to one exact existing Chrome page target |
182
+ | `tabs` | — | — | Print target IDs, titles, and URLs for open page tabs |
183
+ | `--recording PATH.mp4` | — | off | Record the complete goal with an animated cursor |
184
+ | `--interaction-pauses MS` | — | `0` | Wait after moving to a click target, before mousedown |
185
+ | `--screenshot PATH.jpg` | — | off | Save the final browser viewport |
186
+ | `--final-state` | — | off | Include the final semantic page state in stdout JSON |
187
+ | `--field-value LABEL=VALUE` | — | Luna fallback | Type caller-provided test data into the exactly labeled field |
188
+ | `--field-value-env LABEL=NAME` | — | off | Read a sensitive field value from an environment variable |
189
+
190
+ ## Development
191
+
192
+ ```bash
193
+ bun run check
194
+ bun run build
195
+ ./dist/jev-cdp --help
196
+ ```
197
+
198
+ `bun run build` produces a standalone executable for the current operating system and architecture. Chrome remains an external runtime dependency, and FFmpeg remains optional unless recording is requested. No browser or paid API is required by the unit tests.