@jkudish/jev-browser 0.1.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/CHANGELOG.md +14 -0
- package/LICENSE +21 -0
- package/README.md +206 -0
- package/SECURITY.md +17 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +78 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +66 -0
- package/dist/index.js.map +1 -0
- package/dist/lib.d.ts +39 -0
- package/dist/lib.js +117 -0
- package/dist/lib.js.map +1 -0
- package/dist/navigate.d.ts +82 -0
- package/dist/navigate.js +491 -0
- package/dist/navigate.js.map +1 -0
- package/dist/questions.d.ts +19 -0
- package/dist/questions.js +38 -0
- package/dist/questions.js.map +1 -0
- package/package.json +65 -0
- package/scripts/ensure-chromium.mjs +19 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// The Jev question catalog — every question in one place, with the pattern it
|
|
2
|
+
// follows. Changing a question here changes every consumer; link the relevant
|
|
3
|
+
// TypeSafe doc when you change a design.
|
|
4
|
+
import { choice, noul } from "@typesafe-ai/sdk";
|
|
5
|
+
/**
|
|
6
|
+
* The primary Jev call for each step: three independent judgments over the
|
|
7
|
+
* same state. A select action adds one second-stage call for its option (see
|
|
8
|
+
* selectOptionQuestion), so "one call per step" means one primary call.
|
|
9
|
+
* Patterns: fan-out (docs.typesafe.ai/patterns/fan-out.md) — the questions
|
|
10
|
+
* cannot see each other's answers, which is what makes goal_done an honest
|
|
11
|
+
* cross-check on the action Choice rather than a rationalization of it.
|
|
12
|
+
*/
|
|
13
|
+
export function stepQuestions(criteria) {
|
|
14
|
+
return {
|
|
15
|
+
action: choice("Which single action best advances the task on the current page?", criteria),
|
|
16
|
+
goal_done: noul("The task's goal has been achieved: the current page and history show the sought outcome", {
|
|
17
|
+
true: "The page being viewed is the sought destination or shows the sought information",
|
|
18
|
+
false: "The goal is not yet achieved",
|
|
19
|
+
}),
|
|
20
|
+
stuck: noul("The actions so far are not making progress toward the task (repeats, loops, or no change)", {
|
|
21
|
+
true: "Recent actions repeat or nothing changes; a different strategy is needed",
|
|
22
|
+
false: "Progress is visible or the first steps are still reasonable",
|
|
23
|
+
}),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Second stage for native <select> elements, asked only when the step Choice
|
|
28
|
+
* picked select_eN. Option labels are the defined set; Jev picks the value.
|
|
29
|
+
* Two-stage pattern: docs.typesafe.ai (Choice cardinality is bounded at 255).
|
|
30
|
+
*/
|
|
31
|
+
export function selectOptionQuestion(elementDescription, options) {
|
|
32
|
+
const criteria = {};
|
|
33
|
+
options.forEach((label, i) => {
|
|
34
|
+
criteria[`o${i}`] = label.slice(0, 80);
|
|
35
|
+
});
|
|
36
|
+
return choice(`Which option should be selected in the dropdown "${elementDescription}", given the task and the page?`, criteria);
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=questions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"questions.js","sourceRoot":"","sources":["../src/questions.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,8EAA8E;AAC9E,yCAAyC;AACzC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAEhD;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,QAAgC;IAC5D,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,iEAAiE,EAAE,QAAQ,CAAC;QAC3F,SAAS,EAAE,IAAI,CAAC,yFAAyF,EAAE;YACzG,IAAI,EAAE,iFAAiF;YACvF,KAAK,EAAE,8BAA8B;SACtC,CAAC;QACF,KAAK,EAAE,IAAI,CAAC,2FAA2F,EAAE;YACvG,IAAI,EAAE,0EAA0E;YAChF,KAAK,EAAE,6DAA6D;SACrE,CAAC;KACH,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,kBAA0B,EAAE,OAAiB;IAChF,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAC5C,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;QAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CACX,oDAAoD,kBAAkB,iCAAiC,EACvG,QAAQ,CACT,CAAC;AACJ,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@jkudish/jev-browser",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A Jev-driven browser agent as an MCP tool: give it a task and a start URL; it navigates with typed Choice actions, a typed-input cascade, and stop/stuck safety gates.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Joey Kudish",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/jkudish/jev-browser.git"
|
|
11
|
+
},
|
|
12
|
+
"bin": {
|
|
13
|
+
"jev-browser": "dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"scripts",
|
|
18
|
+
"README.md",
|
|
19
|
+
"LICENSE",
|
|
20
|
+
"SECURITY.md",
|
|
21
|
+
"CHANGELOG.md"
|
|
22
|
+
],
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=20"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsc",
|
|
28
|
+
"prepare": "npm run build",
|
|
29
|
+
"typecheck": "tsc --noEmit",
|
|
30
|
+
"test": "node --test test/unit.test.mjs",
|
|
31
|
+
"test:e2e": "node --test test/e2e.test.mjs"
|
|
32
|
+
},
|
|
33
|
+
"postinstall": "node scripts/ensure-chromium.mjs",
|
|
34
|
+
"keywords": [
|
|
35
|
+
"mcp",
|
|
36
|
+
"model-context-protocol",
|
|
37
|
+
"typesafe",
|
|
38
|
+
"jev",
|
|
39
|
+
"browser",
|
|
40
|
+
"agent",
|
|
41
|
+
"playwright",
|
|
42
|
+
"automation"
|
|
43
|
+
],
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@ai-sdk/anthropic": "^2.0.0",
|
|
46
|
+
"@ai-sdk/google": "^1.2.0",
|
|
47
|
+
"@ai-sdk/openai": "^2.0.0",
|
|
48
|
+
"@ai-sdk/openai-compatible": "^1.0.0",
|
|
49
|
+
"@modelcontextprotocol/sdk": "^1.17.0",
|
|
50
|
+
"@typesafe-ai/sdk": "^0.6.0",
|
|
51
|
+
"ai": "^5.0.0",
|
|
52
|
+
"playwright": "^1.55.0",
|
|
53
|
+
"turndown": "^7.2.0",
|
|
54
|
+
"turndown-plugin-gfm": "^1.0.2",
|
|
55
|
+
"zod": "^3.25.0"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@types/node": "^22.0.0",
|
|
59
|
+
"@types/turndown": "^5.0.5",
|
|
60
|
+
"typescript": "^5.6.0"
|
|
61
|
+
},
|
|
62
|
+
"publishConfig": {
|
|
63
|
+
"access": "public"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Downloads Chromium for Playwright unless it is already present or the
|
|
2
|
+
// caller opted out. Keeps `npx -y github:jkudish/jev-browser` self-contained:
|
|
3
|
+
// "packages everything it needs to navigate directly".
|
|
4
|
+
import { execFileSync } from "node:child_process";
|
|
5
|
+
|
|
6
|
+
if (process.env.JEV_BROWSER_SKIP_BROWSER_DOWNLOAD === "1" || process.env.PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD === "1") {
|
|
7
|
+
process.exit(0);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
try {
|
|
11
|
+
execFileSync("npx", ["--yes", "playwright", "install", "chromium"], {
|
|
12
|
+
stdio: "inherit",
|
|
13
|
+
env: process.env,
|
|
14
|
+
});
|
|
15
|
+
} catch (error) {
|
|
16
|
+
console.error("[jev-browser] chromium install failed:", error.message);
|
|
17
|
+
console.error("[jev-browser] retry manually with: npx playwright install chromium");
|
|
18
|
+
process.exit(0); // not fatal: an existing system install may still work
|
|
19
|
+
}
|