jevway 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/INSTALL-FOR-AGENTS.md +32 -38
- package/README.md +193 -150
- package/dist/cli/daemon-call.js +78 -0
- package/dist/cli/dispatch.js +74 -0
- package/dist/cli/flags.js +152 -0
- package/dist/cli/help.js +46 -0
- package/dist/cli/journey-command.js +162 -0
- package/dist/cli/look-command.js +47 -0
- package/dist/cli/main.js +64 -0
- package/dist/cli/output.js +27 -0
- package/dist/cli/run-command.js +173 -0
- package/dist/cli/session-commands.js +132 -0
- package/dist/daemon/client.js +175 -0
- package/dist/daemon/paths.js +35 -0
- package/dist/daemon/protocol.js +28 -0
- package/dist/daemon/server.js +320 -0
- package/dist/jev/replay.js +7 -3
- package/dist/jev/retry.js +29 -0
- package/dist/journeys/journey-doc.js +2 -1
- package/dist/journeys/journey-session.js +14 -3
- package/dist/journeys/render-viewer.js +163 -150
- package/dist/mcp/instructions.js +18 -0
- package/dist/mcp/journey-tools.js +117 -0
- package/dist/mcp/results.js +53 -0
- package/dist/mcp/server.js +50 -0
- package/dist/mcp/task-tools.js +197 -0
- package/dist/mcp.js +10 -337
- package/dist/output/layout.js +50 -0
- package/dist/output/manifest.js +80 -0
- package/dist/output/run-folder.js +38 -0
- package/dist/recording/describe-step.js +66 -0
- package/dist/{task → recording}/recording-page.js +164 -18
- package/dist/{task → recording}/recording.js +33 -91
- package/dist/recording/run-page.js +155 -0
- package/dist/session/session-service.js +193 -0
- package/dist/setup/atomic-write.js +13 -0
- package/dist/setup/clients.js +180 -0
- package/dist/setup/command-output.js +15 -0
- package/dist/setup/doctor-command.js +16 -7
- package/dist/setup/doctor.js +17 -2
- package/dist/setup/env-file.js +22 -0
- package/dist/setup/setup-command.js +104 -0
- package/dist/setup/setup-wizard.js +216 -0
- package/dist/setup/skill-command.js +101 -0
- package/dist/setup/terminal-prompter.js +51 -0
- package/dist/setup/unified-diff.js +69 -0
- package/dist/task/present.js +90 -0
- package/dist/task/run-task.js +74 -11
- package/dist/task/start-task.js +21 -5
- package/package.json +9 -7
- package/skill/jevway/SKILL.md +50 -14
- package/dist/cli.js +0 -112
package/INSTALL-FOR-AGENTS.md
CHANGED
|
@@ -4,11 +4,17 @@ You are an agent asked to install jevway for a person. jevway is an MCP server,
|
|
|
4
4
|
It hands browser goals to TypeSafe Jev. Both come from the npm package `jevway`.
|
|
5
5
|
|
|
6
6
|
Read this whole file before you run anything. Run only these:
|
|
7
|
-
- `npx -y jevway doctor` (or `jevway doctor`);
|
|
7
|
+
- `npx -y jevway doctor --json` (or `--plan`, or `jevway doctor`);
|
|
8
|
+
- `npx -y jevway setup --client <name> --print [--json]`, which prints how to register jevway with a client and
|
|
9
|
+
changes nothing;
|
|
10
|
+
- `npx -y jevway skill --install <skills folder>`;
|
|
8
11
|
- `npm install -g jevway`;
|
|
9
12
|
- the client's own `mcp add` command, or an edit to its MCP config file that the person approved.
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
Never run plain `jevway setup` yourself: it is the person's interactive setup, and without a terminal it exits 2 with
|
|
15
|
+
`{ "ok": false, "error": { "code": "needs_tty", … } }`.
|
|
16
|
+
|
|
17
|
+
Done means: `jevway doctor --json` prints `"ready": true` (exit 0), and the client lists the `jevway_*` tools.
|
|
12
18
|
|
|
13
19
|
## Rules
|
|
14
20
|
|
|
@@ -29,10 +35,11 @@ Done means: `jevway doctor` exits 0, and the client lists the `jevway_*` tools.
|
|
|
29
35
|
## 1. Check the machine
|
|
30
36
|
|
|
31
37
|
```bash
|
|
32
|
-
npx -y jevway doctor --
|
|
38
|
+
npx -y jevway doctor --json
|
|
33
39
|
```
|
|
34
40
|
|
|
35
|
-
It prints
|
|
41
|
+
It prints `{ ready, findings: [{ check, level, message, fix? }] }`; `--plan` prints the steps still missing, numbered.
|
|
42
|
+
It needs no key to run and never prints one. It checks:
|
|
36
43
|
- Node 24 or later;
|
|
37
44
|
- a key, and which route it selects;
|
|
38
45
|
- the browser source;
|
|
@@ -47,7 +54,11 @@ jevway needs one of these:
|
|
|
47
54
|
- `TYPESAFE_API_KEY` (preferred): Jev on the TypeSafe API, with screenshots and Box.
|
|
48
55
|
- `OPENROUTER_API_KEY`: Jev, and the other models, through OpenRouter.
|
|
49
56
|
|
|
50
|
-
|
|
57
|
+
The easiest way for the person: run `npx -y jevway setup` in their own terminal. It reads the key with hidden input,
|
|
58
|
+
writes only that line to `~/.config/jevway/env` (mode 600), tests the browser, and offers to register their MCP
|
|
59
|
+
clients, showing each change first.
|
|
60
|
+
|
|
61
|
+
Or they add the line themselves, in their own editor or terminal, never in this chat:
|
|
51
62
|
|
|
52
63
|
```bash
|
|
53
64
|
mkdir -p ~/.config/jevway && touch ~/.config/jevway/env && chmod 600 ~/.config/jevway/env
|
|
@@ -73,39 +84,16 @@ Use the server name `jevway`. Add `JEVWAY_BROWSER` only if the person chose some
|
|
|
73
84
|
/plugin install jevway@jevway
|
|
74
85
|
```
|
|
75
86
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
```bash
|
|
79
|
-
claude mcp add jevway -s user -- npx -y -p jevway jevway-mcp
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
**Codex**:
|
|
87
|
+
Otherwise ask jevway for the exact command or snippet. It prints, and changes nothing:
|
|
83
88
|
|
|
84
89
|
```bash
|
|
85
|
-
|
|
90
|
+
npx -y jevway setup --client claude-code --print # also: codex, cursor, opencode, other
|
|
91
|
+
npx -y jevway setup --client cursor --print --json # { client, kind, command?, file?, snippet }
|
|
86
92
|
```
|
|
87
93
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
[mcp_servers.jevway]
|
|
92
|
-
command = "npx"
|
|
93
|
-
args = ["-y", "-p", "jevway", "jevway-mcp"]
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
**Cursor**: in `~/.cursor/mcp.json`, add to `mcpServers` (diff first):
|
|
97
|
-
|
|
98
|
-
```json
|
|
99
|
-
"jevway": { "command": "npx", "args": ["-y", "-p", "jevway", "jevway-mcp"] }
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
**OpenCode**: in `~/.config/opencode/opencode.json`, add to `mcp` (diff first):
|
|
103
|
-
|
|
104
|
-
```json
|
|
105
|
-
"jevway": { "type": "local", "command": ["npx", "-y", "-p", "jevway", "jevway-mcp"], "enabled": true }
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
**Any other stdio MCP client**: command `npx`, args `["-y", "-p", "jevway", "jevway-mcp"]`.
|
|
94
|
+
- `kind: "command"` (Claude Code, Codex): run `command`. For Codex, `snippet` is the table it writes to `file`.
|
|
95
|
+
- `kind: "config"` (Cursor, OpenCode): merge `snippet` into `file`, keeping every other server; show the person the
|
|
96
|
+
diff first and wait for approval. `other` gives the `command` and `args` for any stdio MCP client.
|
|
109
97
|
|
|
110
98
|
## 4. The browser
|
|
111
99
|
|
|
@@ -119,13 +107,19 @@ args = ["-y", "-p", "jevway", "jevway-mcp"]
|
|
|
119
107
|
|
|
120
108
|
## 5. The skill (clients other than the Claude Code plugin)
|
|
121
109
|
|
|
122
|
-
The skill says when to use `jevway_task` and when to use chrome-devtools. It
|
|
123
|
-
|
|
124
|
-
|
|
110
|
+
The skill says when to use `jevway_task` and when to use chrome-devtools. It ships in the package; `jevway skill`
|
|
111
|
+
prints it, and this copies it into a client's skills folder as `<folder>/jevway/`:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
npx -y jevway skill --install ~/.codex/skills # or ~/.claude/skills, ~/.cursor/skills, ~/.config/opencode/skills
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
It prints `{ ok, status, path, files }`. A different `jevway` skill already there (or a symlink to one) is left alone
|
|
118
|
+
with `"code": "skill_exists"` and exit 1; replace it with `--force` only if the person agrees.
|
|
125
119
|
|
|
126
120
|
## 6. Check the outcome
|
|
127
121
|
|
|
128
|
-
1. `npx -y jevway doctor` exits 0
|
|
122
|
+
1. `npx -y jevway doctor --json` prints `"ready": true` and exits 0 (every finding `ok` or `warn`).
|
|
129
123
|
2. The client lists the tools: `jevway_task`, `jevway_look`, `jevway_end` and `jevway_journey_start`, `_step`,
|
|
130
124
|
`_autopilot`, `_annotate`, `_finish`.
|
|
131
125
|
- In Claude Code: `/mcp`.
|
package/README.md
CHANGED
|
@@ -1,219 +1,262 @@
|
|
|
1
1
|
# jevway
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/jevway)
|
|
4
|
+
[](https://github.com/AbdallahAHO/jevway/actions/workflows/ci.yml)
|
|
5
|
+
[](LICENSE)
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
agent ◀── { status, url, steps, stuck? } ──────┘ (same Chrome chrome-devtools inspects)
|
|
8
|
-
```
|
|
7
|
+
Give your coding agent a browser goal and get back one short, checked summary. [TypeSafe Jev](https://docs.typesafe.ai)
|
|
8
|
+
picks each click, type and select in about 300 ms, so your agent stops spending a turn on every step.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
<!-- Source: docs/images/how-it-flows.mmd (render with @mermaid-js/mermaid-cli: -t default -b white -s 2) -->
|
|
11
|
+

|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
jevway is an MCP server and a CLI. It works with Claude Code, Codex, Cursor, OpenCode and any other MCP client, in your
|
|
14
|
+
own signed-in Chrome or a throwaway one.
|
|
13
15
|
|
|
14
|
-
|
|
16
|
+
## Why
|
|
15
17
|
|
|
16
|
-
|
|
18
|
+
Driving a browser click by click costs an agent a model turn, a page snapshot and a few seconds per step. A 15-step
|
|
19
|
+
form takes minutes and fills the context window with snapshots. jevway hands the whole goal to Jev, a model built to
|
|
20
|
+
choose browser actions, and returns when it's done or when it needs the agent:
|
|
17
21
|
|
|
18
|
-
**
|
|
22
|
+
- **It never invents input.** Jev types only the `values` the agent passed. A missing value comes back as
|
|
23
|
+
`needs_input`, naming the field.
|
|
24
|
+
- **It stops before anything irreversible.** Pay, send, delete and submit come back as `needs_confirmation`. One
|
|
25
|
+
confirmation allows one click, on the control that was named.
|
|
26
|
+
- **It checks its own success.** `done` needs a separate check of `done_when` on the final page, plus any exact
|
|
27
|
+
`checks` you add, and comes with the page's own words as evidence.
|
|
28
|
+
- **Model output only ever selects a listed element.** It never becomes a selector, a script or typed text.
|
|
29
|
+
- **It can record what it did.** A video of the run, a screenshot before every action, and an HTML page to review it,
|
|
30
|
+
built in. See [Recordings](#recordings).
|
|
19
31
|
|
|
20
|
-
|
|
21
|
-
/plugin marketplace add AbdallahAHO/jevway
|
|
22
|
-
/plugin install jevway@jevway
|
|
23
|
-
```
|
|
32
|
+
## What you need
|
|
24
33
|
|
|
25
|
-
|
|
34
|
+
jevway has no browser extension and no Playwright: it drives Chrome directly. Three things are required, and two
|
|
35
|
+
optional tools unlock more.
|
|
26
36
|
|
|
27
|
-
|
|
37
|
+
| | Needed for | Without it |
|
|
38
|
+
| --- | --- | --- |
|
|
39
|
+
| **Node.js 24+** | running jevway (`npx` fetches it) | it won't start |
|
|
40
|
+
| **Google Chrome** (or Chromium) | every run: your running Chrome, or a throwaway one jevway starts | runs fail; set `CHROME_PATH` if Chrome isn't in the usual place |
|
|
41
|
+
| **An API key**: `TYPESAFE_API_KEY` (recommended) or `OPENROUTER_API_KEY` | every decision Jev makes | the server still starts and lists its tools, and `jevway_look` works, but tasks and journeys answer with the setup fix |
|
|
42
|
+
| `ffmpeg` *(optional)* | the `run.mp4` video in a recording | recordings keep their step screenshots and HTML page, without the video |
|
|
43
|
+
| chrome-devtools MCP *(optional)* | inspecting what jevway left on screen: console, network, performance, DOM details | nothing is lost in jevway itself; your agent just has no deeper inspection tool |
|
|
28
44
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
```
|
|
45
|
+
**Which key?** Both run the same Jev model. The TypeSafe key adds **Box**, which locates controls on the screenshot:
|
|
46
|
+
it double-checks the click Jev chose and whether it's covered, rescues a step when Jev is stuck, can click a canvas
|
|
47
|
+
control (opt-in), and marks each journey screen's primary action and the controls missing from the page's code. Through OpenRouter those Box features are off; everything else works.
|
|
33
48
|
|
|
34
|
-
|
|
49
|
+
`npx -y jevway doctor` checks all of this and names the fix for anything missing.
|
|
35
50
|
|
|
36
|
-
|
|
37
|
-
"jevway": { "command": "npx", "args": ["-y", "-p", "jevway", "jevway-mcp"] }
|
|
38
|
-
```
|
|
51
|
+
## Quick start
|
|
39
52
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
```json
|
|
43
|
-
"jevway": { "type": "local", "command": ["npx", "-y", "-p", "jevway", "jevway-mcp"], "enabled": true }
|
|
44
|
-
```
|
|
53
|
+
1. **Get a key** from [TypeSafe](https://docs.typesafe.ai) (or use an [OpenRouter](https://openrouter.ai) key).
|
|
45
54
|
|
|
46
|
-
**
|
|
47
|
-
into a chat or a synced client config:
|
|
55
|
+
2. **Run the setup** in your terminal:
|
|
48
56
|
|
|
49
|
-
```bash
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
```
|
|
57
|
+
```bash
|
|
58
|
+
npx -y jevway setup
|
|
59
|
+
```
|
|
53
60
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
- Without a key the server still starts and lists its tools: `jevway_look` works, and the other tools answer with the fix.
|
|
61
|
+
It asks for the key without showing it and saves it to `~/.config/jevway/env` (mode 600, never a chat or a synced
|
|
62
|
+
config), tests the browser, and registers jevway with the clients it finds: Claude Code, Codex, Cursor, OpenCode.
|
|
63
|
+
Every change is shown first, as a command or a diff, and made only on a yes. It ends with `jevway doctor`.
|
|
58
64
|
|
|
59
|
-
|
|
65
|
+
In Claude Code you can instead install the plugin, which brings the server and the skill that tells the agent when
|
|
66
|
+
to use it (then put the key in `~/.config/jevway/env` yourself):
|
|
60
67
|
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
```
|
|
68
|
+
```text
|
|
69
|
+
/plugin marketplace add AbdallahAHO/jevway
|
|
70
|
+
/plugin install jevway@jevway
|
|
71
|
+
```
|
|
66
72
|
|
|
67
|
-
|
|
68
|
-
|
|
73
|
+
3. **Allow the browser.** By default jevway uses your running Chrome: open `chrome://inspect/#remote-debugging` and
|
|
74
|
+
allow it. To use a throwaway browser instead, set `JEVWAY_BROWSER=launch`.
|
|
69
75
|
|
|
70
|
-
|
|
76
|
+
4. **Ask your agent** for something in the browser: "Find a 2-night stay in Lisbon for 2 guests under €150 and open the
|
|
77
|
+
best-rated one."
|
|
71
78
|
|
|
72
|
-
`
|
|
79
|
+
`npx -y jevway doctor` checks the setup at any time (`--json` for agents) and names the fix for anything missing.
|
|
73
80
|
|
|
74
|
-
|
|
75
|
-
- `launch` or `launch-headless`: a throwaway profile.
|
|
76
|
-
- `http://127.0.0.1:9222`: an explicit debugging port.
|
|
81
|
+
## Install
|
|
77
82
|
|
|
78
|
-
|
|
79
|
-
your agent's skills, so it knows when to use Jev and when to use chrome-devtools.
|
|
83
|
+
**Claude Code:** the plugin above, or the server alone:
|
|
80
84
|
|
|
81
|
-
|
|
85
|
+
```bash
|
|
86
|
+
claude mcp add jevway -s user -- npx -y -p jevway jevway-mcp
|
|
87
|
+
```
|
|
82
88
|
|
|
83
|
-
|
|
89
|
+
**Codex:**
|
|
84
90
|
|
|
85
91
|
```bash
|
|
86
|
-
npx -y jevway
|
|
87
|
-
--url https://en.wikipedia.org/wiki/Main_Page \
|
|
88
|
-
--goal "Open the Wikipedia article about the Rosetta Stone" \
|
|
89
|
-
--values '{"search_query":"Rosetta Stone"}' \
|
|
90
|
-
--done-when "The Rosetta Stone article is open"
|
|
91
|
-
# prints the JSON summary; exit 0 only when status is "done"
|
|
92
|
+
codex mcp add jevway -- npx -y -p jevway jevway-mcp
|
|
92
93
|
```
|
|
93
94
|
|
|
94
|
-
|
|
95
|
+
**Cursor** (`~/.cursor/mcp.json`, under `mcpServers`) **or any stdio MCP client:**
|
|
95
96
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
| --- | --- | --- | --- | --- |
|
|
100
|
-
| `jev` (default) | `jev-1.14.0` (TypeSafe API: `assets` + Box) / `typesafe/jev-1.14` (OpenRouter) | `fallback` | direct: 7/7 `fallback` and `always`, 6/6 off, ~240 ms/request | 8/8 off and `always` |
|
|
101
|
-
| `pplx-decider` | `perplexity/pplx-decider-v1.1-27b` | `always` | 6/6 off and `always`, 0.4–1.3 s/request | 8/8 |
|
|
102
|
-
| `clef-omni` | `cloudflare/clef-omni` | `always` | 4/6 (3/6 off) | 7/8 (8/8 off) |
|
|
103
|
-
| `clef` | `cloudflare/clef` | none (images cost 16k tokens) | 6/6, 0.7–1.2 s/request | — |
|
|
104
|
-
| `clef-flash` | `cloudflare/clef-flash` | `always` | 1/6 | — |
|
|
105
|
-
| `gpt-6-luna` | `openai/gpt-6-luna-decisions` | `always` | 0–1/6: OpenAI refuses target questions (502) | — |
|
|
97
|
+
```json
|
|
98
|
+
"jevway": { "command": "npx", "args": ["-y", "-p", "jevway", "jevway-mcp"] }
|
|
99
|
+
```
|
|
106
100
|
|
|
107
|
-
**
|
|
101
|
+
**OpenCode** (`opencode.json`, under `mcp`):
|
|
108
102
|
|
|
109
|
-
|
|
103
|
+
```json
|
|
104
|
+
"jevway": { "type": "local", "command": ["npx", "-y", "-p", "jevway", "jevway-mcp"], "enabled": true }
|
|
105
|
+
```
|
|
110
106
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
-
|
|
107
|
+
Outside the Claude Code plugin, copy `skill/jevway/` into your agent's skills folder, so it knows when to use jevway and
|
|
108
|
+
when to use chrome-devtools. If a client times out on `npx`'s first download, run `npm install -g jevway` once and use
|
|
109
|
+
`jevway-mcp` as the command.
|
|
114
110
|
|
|
115
|
-
|
|
111
|
+
Having an agent install it? `npx -y jevway setup --client <claude-code|codex|cursor|opencode|other> --print` prints the
|
|
112
|
+
exact command or config for that client and changes nothing. [INSTALL-FOR-AGENTS.md](INSTALL-FOR-AGENTS.md) has the
|
|
113
|
+
steps per client, the rules (a diff before any config edit, no key in the chat) and the checks.
|
|
116
114
|
|
|
117
|
-
|
|
115
|
+
**Choosing a browser** (`JEVWAY_BROWSER` in the server's env or the env file):
|
|
118
116
|
|
|
119
|
-
|
|
117
|
+
| Value | Uses |
|
|
118
|
+
| --- | --- |
|
|
119
|
+
| `auto` (default) | your running Chrome, after you allow it at `chrome://inspect/#remote-debugging` |
|
|
120
|
+
| `launch` / `launch-headless` | a throwaway profile jevway starts and closes |
|
|
121
|
+
| `http://127.0.0.1:9222` | a Chrome you started with that debugging port and its own profile |
|
|
120
122
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
- **Journeys:** each screen's primary action is boxed (a dashed outline in the viewer, `primary_action` in reports). A tappable control with no DOM element becomes a `control_not_in_dom` QA finding.
|
|
123
|
+
**Without MCP**, use the CLI. It's built for agents: every command prints exactly one JSON document on stdout (the
|
|
124
|
+
result, or `{ "ok": false, "error": { "code", "message", "hint" } }`), progress goes to stderr as one JSON event per
|
|
125
|
+
line, and the exit code is 0 for success, 1 for a hand-back or a failure, 2 for bad usage. `--help` starts with
|
|
126
|
+
examples, and `jevway skill` prints the skill that matches the installed version.
|
|
126
127
|
|
|
127
|
-
|
|
128
|
+
```bash
|
|
129
|
+
# One-shot: runs, closes its tab, prints the result
|
|
130
|
+
npx -y jevway run --browser launch-headless --url https://en.wikipedia.org \
|
|
131
|
+
--goal "Open the Wikipedia article about the Rosetta Stone" --done-when "The Rosetta Stone article is open"
|
|
132
|
+
|
|
133
|
+
# A session: a background daemon keeps the tab between commands, so a hand-back can be answered
|
|
134
|
+
jevway run --session new --url https://example-stays.com --goal "Book 2 nights in Lisbon" --values '{"city":"Lisbon"}'
|
|
135
|
+
jevway run --session <id> --goal "Book 2 nights in Lisbon" --values '{"email":"ada@example.com"}'
|
|
136
|
+
jevway look --session <id> # what the page shows now, no model request
|
|
137
|
+
jevway sessions # open sessions; jevway end <id> closes one
|
|
138
|
+
```
|
|
128
139
|
|
|
129
|
-
##
|
|
140
|
+
## Use
|
|
130
141
|
|
|
131
|
-
|
|
142
|
+
The agent calls `jevway_task` with the outcome it wants, the values it may type, and the evidence of success:
|
|
132
143
|
|
|
133
144
|
```json
|
|
134
|
-
{
|
|
135
|
-
"url": "
|
|
136
|
-
"
|
|
137
|
-
"
|
|
138
|
-
"
|
|
139
|
-
"
|
|
145
|
+
{
|
|
146
|
+
"url": "https://example-stays.com",
|
|
147
|
+
"goal": "Search stays in Lisbon for 2 guests, filter to free cancellation, and open the first result",
|
|
148
|
+
"values": { "destination": "Lisbon", "guests": "2" },
|
|
149
|
+
"done_when": "A stay's detail page is open",
|
|
150
|
+
"allowed_hosts": ["example-stays.com"]
|
|
151
|
+
}
|
|
140
152
|
```
|
|
141
153
|
|
|
142
|
-
|
|
154
|
+
It gets back one concise result, `status` and `reason` first:
|
|
155
|
+
|
|
156
|
+
```json
|
|
157
|
+
{ "status": "done", "reason": "Completion condition verified: a stay's detail page is open.",
|
|
158
|
+
"story": ["Typed the \"destination\" value into \"Destination\".", "Clicked \"Search\".", "Clicked \"Casa Flora\"."],
|
|
159
|
+
"next": "Read the result in `page_text` (and `evidence`); end the session when you no longer need its tab.",
|
|
160
|
+
"session": "a63a13f0-…", "url": "…", "title": "Casa Flora · Staylist",
|
|
161
|
+
"files": { "run_dir": "…/.jevway/runs/2026-11-02_1028_search-stays-in-lisbon_a63a", "screenshot": "…/final.jpg" },
|
|
162
|
+
"page_text": "…" }
|
|
163
|
+
```
|
|
143
164
|
|
|
144
|
-
`
|
|
165
|
+
`story` says what happened in plain sentences, `next` says what to do now, and `files` points at the run folder and a
|
|
166
|
+
screenshot of the end page. On a hand-back the screenshot also comes inline, so the agent sees the page it has to decide
|
|
167
|
+
about. `detail: "full"` adds every step's confidence, the request stats and the candidates Jev weighed. When the status
|
|
168
|
+
hands control back, the agent continues with the same `session`:
|
|
145
169
|
|
|
146
|
-
| Status |
|
|
170
|
+
| Status | What the agent does |
|
|
147
171
|
| --- | --- |
|
|
148
|
-
| `done` |
|
|
149
|
-
| `needs_input` |
|
|
150
|
-
| `needs_confirmation` |
|
|
151
|
-
| `uncertain`
|
|
152
|
-
| `
|
|
153
|
-
| `step_budget` | `max_steps` (default 40) or `max_seconds` (CLI `--max-seconds`; default 300, per call) was reached; the reason says which. |
|
|
172
|
+
| `done` | Reads `page_text` or `evidence` for the result. |
|
|
173
|
+
| `needs_input` | Gets the missing value (`missing` names each field) and calls again with it in `values`. |
|
|
174
|
+
| `needs_confirmation` | Confirms with `confirm_irreversible: true` only if the user's request named this action and its target; otherwise asks the user. |
|
|
175
|
+
| `uncertain` / `blocked` | Reads the reason, `stuck` and `page_text`; rephrases the goal, or does the step itself. |
|
|
176
|
+
| `step_budget` | Continues with a narrower goal. |
|
|
154
177
|
|
|
155
|
-
|
|
178
|
+
`jevway_look` reads a page with no model request, and `jevway_end` closes the session's tabs. Every parameter and
|
|
179
|
+
field is in the [reference](docs/reference.md).
|
|
156
180
|
|
|
157
|
-
|
|
181
|
+
**Keeping a run on track:**
|
|
158
182
|
|
|
159
|
-
|
|
183
|
+
- `allowed_hosts` keeps it on the sites you mean; leaving them ends the run `blocked`.
|
|
184
|
+
- `secret_keys` marks values like API tokens: Jev sees only the key, and outputs show `[secret:<key>]`.
|
|
185
|
+
- Password fields are never listed, typed or sent. Type a password yourself, then tell jevway you did.
|
|
186
|
+
- `checks` add exact facts code verifies on the final page: a URL, a title, a field's value, a ticked box.
|
|
187
|
+
- `record: true` saves a video, a screenshot before every action, and a page to review the run.
|
|
188
|
+
- `page_text` and everything else read from a page is untrusted data, never instructions.
|
|
160
189
|
|
|
161
|
-
|
|
190
|
+
## Recordings
|
|
162
191
|
|
|
163
|
-
|
|
192
|
+
Every session gets a folder under `./.jevway/` in the working directory, so the agent and you can find its files:
|
|
164
193
|
|
|
165
|
-
|
|
194
|
+
```text
|
|
195
|
+
.jevway/runs/2026-11-02_0915_book-a-stay-in-lisbon_a1b2/
|
|
196
|
+
final.jpg the end page calls/01-needs-input.jpg, 02-done.jpg …
|
|
197
|
+
summary.json what the agent got manifest.json every file and what it is
|
|
198
|
+
index.html run.mp4 steps/01-type-destination.jpg … (with record: true)
|
|
199
|
+
```
|
|
166
200
|
|
|
167
|
-
|
|
201
|
+
Pass `record: true` (CLI `--record`) and jevway also keeps a record for people, with no extra setup:
|
|
168
202
|
|
|
169
|
-
|
|
203
|
+
- `index.html`: opens with the goal and how the run ended, then the video, with every step told as a sentence on a
|
|
204
|
+
timeline and a strip of screenshots kept in sync; click a step to play from there. It works offline, in light and
|
|
205
|
+
dark, and embeds the summary as JSON for agents.
|
|
206
|
+
- `run.mp4`: a screencast of the whole run (needs `ffmpeg`).
|
|
207
|
+
- A sharp screenshot before every action, named for what it did, with its target outlined and labelled.
|
|
170
208
|
|
|
171
|
-
|
|
209
|
+

|
|
172
210
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
- Every input re-checks the page for freshness and for covered targets first (from jev-ultrafast).
|
|
176
|
-
- Page text is treated as untrusted data in every instruction.
|
|
177
|
-
- **Hosts:** `allowed_hosts` / `blocked_hosts` (CLI `--allowed-hosts`, `--blocked-hosts`; server-wide `JEVWAY_ALLOWED_HOSTS`, `JEVWAY_BLOCKED_HOSTS`) take exact hosts or `*.example.com` (subdomains only, not `example.com`). A call can only narrow the server's lists, and a later call only the session's. A start URL outside is never opened; the page URL is checked before every decision and after every step, and leaving ends the run `blocked` naming the host. The run never navigates back. `about:blank` and Chrome error pages always pass; `data:`, `file:` and other host-less pages are outside an allowed list. Only the top page's URL is checked: iframes, popup tabs and the page's own requests are not.
|
|
211
|
+
Values marked secret are masked in the text files; screenshots and video show the page as it was. The model never sees
|
|
212
|
+
these images. Journey maps get their own viewer, described next.
|
|
178
213
|
|
|
179
|
-
##
|
|
214
|
+
## Journey maps
|
|
180
215
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
pnpm report:render verify/out/<folder> # rebuild a suite's report.html (or a run folder's index.html), offline
|
|
187
|
-
pnpm verify:replay --record verify/out/replay/<name> # live: record every Jev answer of the fixture suites
|
|
188
|
-
pnpm verify:replay verify/out/replay/<name> # offline: replay them, no key, no credits
|
|
189
|
-
```
|
|
216
|
+
The `jevway_journey_*` tools map how a person moves through a site on a phone: every screen with its type and UI
|
|
217
|
+
patterns, the taps between them, and QA findings like tap targets under 44 px, console errors and dead ends. You pick
|
|
218
|
+
the taps, or let Jev explore. The result is a shareable viewer. See [docs/journeys.md](docs/journeys.md).
|
|
219
|
+
|
|
220
|
+
## How it works
|
|
190
221
|
|
|
191
|
-
|
|
222
|
+
Each step, jevway reads the page through the Chrome DevTools Protocol into a numbered list of controls and the visible
|
|
223
|
+
text, and sends one request to Jev with the goal, that list and the names of the supplied values. Jev answers with an
|
|
224
|
+
operation, a listed element, which value to type, its confidence and a commit-risk score. Code checks the answer
|
|
225
|
+
against the list, re-checks the page is fresh and the target isn't covered, and acts with real input events. Guards
|
|
226
|
+
stop loops, and a separate check decides `done`.
|
|
192
227
|
|
|
193
|
-
|
|
194
|
-
- **Real Wikipedia search.**
|
|
195
|
-
- **Canvas-only control** (Box profiles with screenshots): no click without the opt-in, and the game starts with it.
|
|
196
|
-
- **Wide table rows** (like Langfuse's traces table): rows wider than their scroll box are listed and opened, not their checkboxes. The run is recorded.
|
|
197
|
-
- **MCP stdio round trip.**
|
|
228
|
+
The full technical specification is in [docs/how-it-works.md](docs/how-it-works.md).
|
|
198
229
|
|
|
199
|
-
|
|
230
|
+
## Models
|
|
231
|
+
|
|
232
|
+
Jev 1.14 is the default, on the TypeSafe API with `TYPESAFE_API_KEY` (with screenshots and Box, which locates
|
|
233
|
+
controls on the screenshot to cross-check and rescue clicks) or through OpenRouter with `OPENROUTER_API_KEY`. Perplexity's and Cloudflare's decision models run through
|
|
234
|
+
OpenRouter too. Jev is priced at $0.042 per 1M input tokens, so a typical 10-step task costs well under a cent. See
|
|
235
|
+
[Models](docs/reference.md#models) for results per model.
|
|
236
|
+
|
|
237
|
+
## Documentation
|
|
238
|
+
|
|
239
|
+
| Doc | For |
|
|
240
|
+
| --- | --- |
|
|
241
|
+
| [docs/reference.md](docs/reference.md) | every tool, parameter, status, CLI flag, environment variable and model |
|
|
242
|
+
| [docs/how-it-works.md](docs/how-it-works.md) | the technical specification: one step end to end, guards, safety |
|
|
243
|
+
| [docs/journeys.md](docs/journeys.md) | the journey-map tools |
|
|
244
|
+
| [INSTALL-FOR-AGENTS.md](INSTALL-FOR-AGENTS.md) | agents installing jevway for a person |
|
|
245
|
+
| [skill/jevway/SKILL.md](skill/jevway/SKILL.md) | the skill agents load: when and how to call jevway |
|
|
246
|
+
| [docs/verification.md](docs/verification.md) | the test suites and their results |
|
|
247
|
+
| [docs/prior-art.md](docs/prior-art.md) | other open-source Jev browser projects, and what was taken from them |
|
|
248
|
+
| [CONTRIBUTING.md](CONTRIBUTING.md) | building, testing and releasing |
|
|
200
249
|
|
|
201
|
-
|
|
250
|
+
## Contributing
|
|
202
251
|
|
|
203
|
-
|
|
252
|
+
Bug reports, site failures and pull requests are welcome. [CONTRIBUTING.md](CONTRIBUTING.md) covers the setup, the
|
|
253
|
+
offline test suite (no API key needed) and the conventions. Report security issues privately, as described in
|
|
254
|
+
[SECURITY.md](SECURITY.md).
|
|
204
255
|
|
|
205
|
-
|
|
256
|
+
## License
|
|
206
257
|
|
|
207
|
-
|
|
258
|
+
MIT. The task loop, DOM snapshot and guards build on [browser-use/jev-ultrafast](https://github.com/browser-use/jev-ultrafast)
|
|
259
|
+
(MIT; see [LICENSE.jev-ultrafast](LICENSE.jev-ultrafast)).
|
|
208
260
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
- The DOM reader covers common HTML/ARIA controls, including inside open shadow roots and iframes. Every visible frame, same-origin or cross-origin (out-of-process frames too), is read with the same reader: its controls continue the page's numbering, its text follows the page's under `[Frame: …]` within the same 6000 characters, and clicks, typing and every guard run inside the frame. A frame is skipped when it shows less than 16×16 px, sits outside an open modal, is still blank, takes over 1.5 s to read, or is past the caps (10 frames, 3 levels deep); controls a banner or sheet covers in the page around the frame aren't listed. CSS-transformed (scaled, rotated) iframes are placed as if untransformed.
|
|
212
|
-
- Closed shadow roots and canvas aren't read, and file inputs inside iframes aren't supported: they are not listed, and an upload is never set inside a frame. Box can see canvas controls (and frames skipped above), and click them with the opt-in; otherwise use chrome-devtools.
|
|
213
|
-
- Uploads take only files the caller declares in `files` (key → absolute path, checked before the run), never a path from `values`. Only then are file inputs listed (hidden ones through their label or styled button) and UPLOAD offered; Jev sees each key and file name, never the path, and a native file picker is intercepted. No declared file fitting a field is `needs_input`.
|
|
214
|
-
- A tab the session's own click opens (`target=_blank`, `window.open`) is followed, and a closed one falls back to the tab that opened it; tabs anyone else opens are never touched. `jevway_end` closes the tabs the session's clicks opened (and its first tab when it opened it) unless `keep_tab`. The new tab is set up when it appears, so on a page that loads within ~20 ms its first document's own scripts run before the click counter; that can only end a run `blocked`, never repeat a click. A dialog the new tab raises before it is set up freezes it; following then fails after 5 s and the run ends `blocked`. In `auto` mode Chrome shows the new tab in front. A `record_dir` video stays on the first tab.
|
|
215
|
-
- Only on-screen elements are listed; Jev scrolls to reveal more. On a page whose document doesn't scroll (an app shell), the scroll goes to the largest visible pane that does; a scroll that moved nothing is reported to Jev as such. Exception: an off-screen link, button or row containing one of the supplied `values` is listed too, and scrolled into view when clicked.
|
|
216
|
-
- The scroll aimed at an inner pane works on the main page only; inside an iframe, scrolling stays page-level.
|
|
217
|
-
- Confidence thresholds (per model, in `src/jev/model.ts`) and the 0.5 risk threshold are starting points, tuned on a small set of runs.
|
|
218
|
-
- Jev's commit-risk check is a speculative page-level judgment ("the click that best advances the goal") plus a per-element score for the chosen click; the higher one counts. Other models score each candidate only, and Box rescues use the box's own score.
|
|
219
|
-
- A click scoring 0.25–0.5 on risk gets a screenshot look before it runs, but only with screenshots on (`fallback` or `always`). With screenshots `off`, text alone under-reads some checkout pages (a bare "Continue" can score under 0.5), so keep screenshots on when a task can reach a payment step.
|
|
261
|
+
jevway was called jev-browse until 0.1.0. Its old tool names (`browser_task`, `browser_look`, `browser_task_end`,
|
|
262
|
+
`journey_*`) and `JEV_*` environment variables no longer work.
|