zelari-code 1.17.1 → 1.18.1
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/dist/cli/browser/driver.js +133 -3
- package/dist/cli/browser/driver.js.map +1 -1
- package/dist/cli/browser/tools.js +60 -11
- package/dist/cli/browser/tools.js.map +1 -1
- package/dist/cli/main.bundled.js +487 -19
- package/dist/cli/main.bundled.js.map +4 -4
- package/dist/cli/main.js +13 -0
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/plugins/cliFlags.js +91 -0
- package/dist/cli/plugins/cliFlags.js.map +1 -0
- package/dist/cli/plugins/installer.js +73 -11
- package/dist/cli/plugins/installer.js.map +1 -1
- package/package.json +2 -2
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
* The "visual verification loop" for web projects: after the agent edits a UI,
|
|
5
5
|
* it navigates the running app and gets back the signals an LLM can actually
|
|
6
6
|
* act on — console errors, uncaught page exceptions, failed network requests,
|
|
7
|
-
* the final title/URL, whether an expected selector is present,
|
|
8
|
-
* screenshot path. Far stronger than "the tests pass"
|
|
7
|
+
* the final title/URL, whether an expected selector is present, evaluate
|
|
8
|
+
* results, and a saved screenshot path. Far stronger than "the tests pass"
|
|
9
|
+
* for front-end work.
|
|
9
10
|
*
|
|
10
11
|
* Playwright is an OPTIONAL dependency, loaded via dynamic import so it is not
|
|
11
12
|
* a hard requirement of the package. When it (or a browser) isn't available,
|
|
@@ -19,6 +20,12 @@
|
|
|
19
20
|
import { createRequire } from 'node:module';
|
|
20
21
|
import path from 'node:path';
|
|
21
22
|
import { pathToFileURL } from 'node:url';
|
|
23
|
+
/** Max length of an evaluate expression (chars). */
|
|
24
|
+
const MAX_EVAL_EXPR = 4_000;
|
|
25
|
+
/** Max JSON-serialized evaluate result size. */
|
|
26
|
+
const MAX_EVAL_RESULT = 8_000;
|
|
27
|
+
/** Max body text sample returned to the agent. */
|
|
28
|
+
const MAX_BODY_SNIPPET = 2_000;
|
|
22
29
|
/** Coerce a dynamic-import module shape into PlaywrightLike (or null). */
|
|
23
30
|
function asPlaywright(mod) {
|
|
24
31
|
if (!mod || typeof mod !== 'object')
|
|
@@ -74,6 +81,50 @@ export async function loadPlaywright(cwd) {
|
|
|
74
81
|
* Prefer `loadPlaywright(explicitCwd)` at call sites that know the workspace.
|
|
75
82
|
*/
|
|
76
83
|
export const defaultPlaywrightLoader = async () => loadPlaywright(process.cwd());
|
|
84
|
+
/** Cap and JSON-safe-clone evaluate return values for the agent. */
|
|
85
|
+
export function serializeEvaluateValue(value) {
|
|
86
|
+
try {
|
|
87
|
+
const json = JSON.stringify(value, (_k, v) => {
|
|
88
|
+
if (typeof v === 'function')
|
|
89
|
+
return '[Function]';
|
|
90
|
+
if (typeof v === 'bigint')
|
|
91
|
+
return v.toString();
|
|
92
|
+
if (v instanceof Error)
|
|
93
|
+
return { name: v.name, message: v.message };
|
|
94
|
+
return v;
|
|
95
|
+
});
|
|
96
|
+
if (json === undefined)
|
|
97
|
+
return null;
|
|
98
|
+
if (json.length > MAX_EVAL_RESULT) {
|
|
99
|
+
return {
|
|
100
|
+
truncated: true,
|
|
101
|
+
preview: json.slice(0, MAX_EVAL_RESULT),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
return JSON.parse(json);
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
return {
|
|
108
|
+
error: `non-serializable: ${err instanceof Error ? err.message : String(err)}`,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Wrap a user expression as a Playwright evaluate **function body**.
|
|
114
|
+
* Playwright treats string pageFunctions as `function(){ <body> }`, so we
|
|
115
|
+
* must `return` the value.
|
|
116
|
+
*/
|
|
117
|
+
export function wrapEvaluateExpression(expression) {
|
|
118
|
+
const expr = expression.trim();
|
|
119
|
+
if (!expr)
|
|
120
|
+
return 'return undefined';
|
|
121
|
+
// Multi-statement or already has return → use as body (ensure return if missing).
|
|
122
|
+
if (/\breturn\b/.test(expr) || expr.includes('\n')) {
|
|
123
|
+
return expr;
|
|
124
|
+
}
|
|
125
|
+
// Single expression
|
|
126
|
+
return `return (${expr})`;
|
|
127
|
+
}
|
|
77
128
|
/**
|
|
78
129
|
* Navigate to a URL (optionally running a sequence of actions) and collect
|
|
79
130
|
* verification signals. Best-effort — never throws; a missing browser or a
|
|
@@ -83,6 +134,7 @@ export async function runBrowserCheck(options, loader) {
|
|
|
83
134
|
const consoleErrors = [];
|
|
84
135
|
const pageErrors = [];
|
|
85
136
|
const failedRequests = [];
|
|
137
|
+
const evaluateResults = [];
|
|
86
138
|
const base = { ok: false, consoleErrors, pageErrors, failedRequests };
|
|
87
139
|
const resolve = loader ??
|
|
88
140
|
(() => loadPlaywright(options.cwd ?? process.cwd()));
|
|
@@ -90,11 +142,16 @@ export async function runBrowserCheck(options, loader) {
|
|
|
90
142
|
if (!pw) {
|
|
91
143
|
return {
|
|
92
144
|
...base,
|
|
93
|
-
error: 'browser automation unavailable —
|
|
145
|
+
error: 'browser automation unavailable — Playwright is not installed in this workspace. ' +
|
|
146
|
+
'Install it with: `zelari-code --plugins-install playwright --cwd .` ' +
|
|
147
|
+
'(or Desktop banner “Install”, or CLI `/plugins install playwright`, or ' +
|
|
148
|
+
'`npm i -D playwright && npx playwright install chromium`). ' +
|
|
149
|
+
'Then re-run browser_check.',
|
|
94
150
|
};
|
|
95
151
|
}
|
|
96
152
|
const timeout = options.timeoutMs ?? 15_000;
|
|
97
153
|
let browser;
|
|
154
|
+
let textFound;
|
|
98
155
|
try {
|
|
99
156
|
browser = await pw.chromium.launch({ headless: true });
|
|
100
157
|
const page = await browser.newPage();
|
|
@@ -122,6 +179,61 @@ export async function runBrowserCheck(options, loader) {
|
|
|
122
179
|
case 'wait':
|
|
123
180
|
await page.waitForTimeout(action.ms);
|
|
124
181
|
break;
|
|
182
|
+
case 'press': {
|
|
183
|
+
const key = action.key.trim();
|
|
184
|
+
if (!key)
|
|
185
|
+
break;
|
|
186
|
+
if (page.keyboard && typeof page.keyboard.press === 'function') {
|
|
187
|
+
await page.keyboard.press(key, { timeout });
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
// Fallback for fakes / surfaces without keyboard
|
|
191
|
+
await page.evaluate(wrapEvaluateExpression(`document.dispatchEvent(new KeyboardEvent('keydown',{key:${JSON.stringify(key)},bubbles:true})); true`));
|
|
192
|
+
}
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
case 'waitForText': {
|
|
196
|
+
const needle = action.text;
|
|
197
|
+
const t = action.timeoutMs ?? timeout;
|
|
198
|
+
try {
|
|
199
|
+
// String function body: Playwright injects as function(arg) { ... }
|
|
200
|
+
await page.waitForFunction(`return (document.body && (document.body.innerText || document.body.textContent || '')).includes(arguments[0])`, needle, { timeout: t });
|
|
201
|
+
textFound = textFound === false ? false : true;
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
textFound = false;
|
|
205
|
+
}
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
case 'evaluate': {
|
|
209
|
+
const raw = action.expression ?? '';
|
|
210
|
+
if (raw.length > MAX_EVAL_EXPR) {
|
|
211
|
+
evaluateResults.push({
|
|
212
|
+
expression: raw.slice(0, 120) + '…',
|
|
213
|
+
error: `expression too long (max ${MAX_EVAL_EXPR} chars)`,
|
|
214
|
+
});
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
217
|
+
if (!raw.trim()) {
|
|
218
|
+
evaluateResults.push({ expression: raw, error: 'empty expression' });
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
try {
|
|
222
|
+
const wrapped = wrapEvaluateExpression(raw);
|
|
223
|
+
const value = await page.evaluate(wrapped);
|
|
224
|
+
evaluateResults.push({
|
|
225
|
+
expression: raw.length > 200 ? raw.slice(0, 200) + '…' : raw,
|
|
226
|
+
value: serializeEvaluateValue(value),
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
catch (err) {
|
|
230
|
+
evaluateResults.push({
|
|
231
|
+
expression: raw.length > 200 ? raw.slice(0, 200) + '…' : raw,
|
|
232
|
+
error: err instanceof Error ? err.message : String(err),
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
125
237
|
default:
|
|
126
238
|
break;
|
|
127
239
|
}
|
|
@@ -136,6 +248,21 @@ export async function runBrowserCheck(options, loader) {
|
|
|
136
248
|
selectorFound = false;
|
|
137
249
|
}
|
|
138
250
|
}
|
|
251
|
+
let bodyTextSnippet;
|
|
252
|
+
if (options.textSample) {
|
|
253
|
+
try {
|
|
254
|
+
const text = await page.evaluate(wrapEvaluateExpression(`(document.body?.innerText || document.body?.textContent || '').trim()`));
|
|
255
|
+
if (typeof text === 'string' && text.length > 0) {
|
|
256
|
+
bodyTextSnippet =
|
|
257
|
+
text.length > MAX_BODY_SNIPPET
|
|
258
|
+
? text.slice(0, MAX_BODY_SNIPPET) + '…'
|
|
259
|
+
: text;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
catch {
|
|
263
|
+
// ignore
|
|
264
|
+
}
|
|
265
|
+
}
|
|
139
266
|
let screenshotPath;
|
|
140
267
|
if (options.screenshotPath) {
|
|
141
268
|
try {
|
|
@@ -155,6 +282,9 @@ export async function runBrowserCheck(options, loader) {
|
|
|
155
282
|
url: page.url(),
|
|
156
283
|
...(title !== undefined ? { title } : {}),
|
|
157
284
|
...(selectorFound !== undefined ? { selectorFound } : {}),
|
|
285
|
+
...(evaluateResults.length > 0 ? { evaluateResults } : {}),
|
|
286
|
+
...(textFound !== undefined ? { textFound } : {}),
|
|
287
|
+
...(bodyTextSnippet !== undefined ? { bodyTextSnippet } : {}),
|
|
158
288
|
...(screenshotPath ? { screenshotPath } : {}),
|
|
159
289
|
};
|
|
160
290
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"driver.js","sourceRoot":"","sources":["../../../src/cli/browser/driver.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"driver.js","sourceRoot":"","sources":["../../../src/cli/browser/driver.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
* browser/tools — the `browser_check` visual-verification tool.
|
|
3
3
|
*
|
|
4
4
|
* Lets the agent confirm a web change actually works in a real browser:
|
|
5
|
-
* navigate the running app, optionally click/fill, and get back
|
|
6
|
-
* errors, uncaught exceptions, failed requests, the title/URL, whether
|
|
7
|
-
* expected element appeared, and a screenshot path.
|
|
8
|
-
* degrades with install instructions when
|
|
5
|
+
* navigate the running app, optionally click/fill/evaluate/press, and get back
|
|
6
|
+
* console errors, uncaught exceptions, failed requests, the title/URL, whether
|
|
7
|
+
* an expected element/text appeared, evaluate results, and a screenshot path.
|
|
8
|
+
* Optional Playwright dep — degrades with install instructions when absent.
|
|
9
9
|
*/
|
|
10
10
|
import path from 'node:path';
|
|
11
11
|
import os from 'node:os';
|
|
@@ -17,24 +17,54 @@ const ActionSchema = z.discriminatedUnion('type', [
|
|
|
17
17
|
z.object({ type: z.literal('fill'), selector: z.string().min(1), value: z.string() }),
|
|
18
18
|
z.object({ type: z.literal('wait'), ms: z.number().int().positive().max(30_000) }),
|
|
19
19
|
z.object({ type: z.literal('goto'), url: z.string().min(1) }),
|
|
20
|
+
z.object({
|
|
21
|
+
type: z.literal('evaluate'),
|
|
22
|
+
expression: z
|
|
23
|
+
.string()
|
|
24
|
+
.min(1)
|
|
25
|
+
.max(4_000)
|
|
26
|
+
.describe('JS expression or statements run in the page (page.evaluate). Prefer DOM reads ' +
|
|
27
|
+
'(document.querySelector…), not assuming window.game exists. Return JSON-safe values.'),
|
|
28
|
+
}),
|
|
29
|
+
z.object({
|
|
30
|
+
type: z.literal('press'),
|
|
31
|
+
key: z
|
|
32
|
+
.string()
|
|
33
|
+
.min(1)
|
|
34
|
+
.describe('Playwright key name, e.g. "Space", "KeyW", "ArrowLeft", "Enter".'),
|
|
35
|
+
}),
|
|
36
|
+
z.object({
|
|
37
|
+
type: z.literal('waitForText'),
|
|
38
|
+
text: z.string().min(1).describe('Substring that must appear in document body text.'),
|
|
39
|
+
timeoutMs: z.number().int().positive().max(60_000).optional(),
|
|
40
|
+
}),
|
|
20
41
|
]);
|
|
21
42
|
export function createBrowserTool(deps = {}) {
|
|
22
43
|
return {
|
|
23
44
|
name: 'browser_check',
|
|
24
45
|
description: 'Open a URL in a headless browser to VERIFY a web change: optionally run ' +
|
|
25
|
-
'click/fill/goto/wait actions, then report console errors,
|
|
26
|
-
'exceptions, failed network requests,
|
|
27
|
-
'
|
|
28
|
-
'
|
|
29
|
-
'
|
|
46
|
+
'click/fill/goto/wait/press/waitForText/evaluate actions, then report console errors, ' +
|
|
47
|
+
'uncaught page exceptions, failed network requests, final title/URL, selector/text ' +
|
|
48
|
+
'presence, evaluate results, and a screenshot path. ' +
|
|
49
|
+
'Prefer DOM assertions (waitForSelector, waitForText, evaluate on document.querySelector) ' +
|
|
50
|
+
'over window.* globals — ES modules and const keep symbols off window. ' +
|
|
51
|
+
'Absence of console errors after a short wait is WEAK smoke only; assert UI state when ' +
|
|
52
|
+
'claiming a fix is verified. Requires Playwright (optional dependency).',
|
|
30
53
|
permissions: ['network'],
|
|
31
54
|
// A browser launch + navigation can take a while.
|
|
32
55
|
timeoutMs: 60_000,
|
|
33
56
|
inputSchema: z.object({
|
|
34
57
|
url: z.string().min(1).describe('URL to open (e.g. http://localhost:3000).'),
|
|
35
|
-
actions: z
|
|
58
|
+
actions: z
|
|
59
|
+
.array(ActionSchema)
|
|
60
|
+
.optional()
|
|
61
|
+
.describe('Optional sequence of interactions / probes before checking.'),
|
|
36
62
|
waitForSelector: z.string().optional().describe('Assert this CSS selector is present after actions.'),
|
|
37
63
|
screenshot: z.boolean().optional().describe('Save a screenshot (default true).'),
|
|
64
|
+
textSample: z
|
|
65
|
+
.boolean()
|
|
66
|
+
.optional()
|
|
67
|
+
.describe('Include a short body.innerText snippet (HUD / Game Over text).'),
|
|
38
68
|
}),
|
|
39
69
|
execute: async (args, ctx) => {
|
|
40
70
|
const a = args;
|
|
@@ -48,6 +78,7 @@ export function createBrowserTool(deps = {}) {
|
|
|
48
78
|
...(a.actions ? { actions: a.actions } : {}),
|
|
49
79
|
...(a.waitForSelector ? { waitForSelector: a.waitForSelector } : {}),
|
|
50
80
|
...(screenshotPath ? { screenshotPath } : {}),
|
|
81
|
+
...(a.textSample ? { textSample: true } : {}),
|
|
51
82
|
}, deps.loader);
|
|
52
83
|
if (!result.ok) {
|
|
53
84
|
return typedOk({ ok: false, note: result.error ?? 'browser check failed' });
|
|
@@ -56,7 +87,14 @@ export function createBrowserTool(deps = {}) {
|
|
|
56
87
|
const clean = result.consoleErrors.length === 0 &&
|
|
57
88
|
result.pageErrors.length === 0 &&
|
|
58
89
|
result.failedRequests.length === 0 &&
|
|
59
|
-
result.selectorFound !== false
|
|
90
|
+
result.selectorFound !== false &&
|
|
91
|
+
result.textFound !== false;
|
|
92
|
+
const hadDomAssertion = result.selectorFound !== undefined ||
|
|
93
|
+
result.textFound !== undefined ||
|
|
94
|
+
(result.evaluateResults !== undefined && result.evaluateResults.length > 0) ||
|
|
95
|
+
!!result.bodyTextSnippet;
|
|
96
|
+
// Only waits / navigate / screenshot with no errors → weak smoke.
|
|
97
|
+
const onlyWeakSmoke = clean && !hadDomAssertion;
|
|
60
98
|
return typedOk({
|
|
61
99
|
ok: true,
|
|
62
100
|
clean,
|
|
@@ -66,7 +104,18 @@ export function createBrowserTool(deps = {}) {
|
|
|
66
104
|
pageErrors: result.pageErrors,
|
|
67
105
|
failedRequests: result.failedRequests,
|
|
68
106
|
...(result.selectorFound !== undefined ? { selectorFound: result.selectorFound } : {}),
|
|
107
|
+
...(result.evaluateResults ? { evaluateResults: result.evaluateResults } : {}),
|
|
108
|
+
...(result.textFound !== undefined ? { textFound: result.textFound } : {}),
|
|
109
|
+
...(result.bodyTextSnippet ? { bodyTextSnippet: result.bodyTextSnippet } : {}),
|
|
69
110
|
...(result.screenshotPath ? { screenshotPath: result.screenshotPath } : {}),
|
|
111
|
+
...(onlyWeakSmoke
|
|
112
|
+
? {
|
|
113
|
+
note: 'Weak smoke only: no selector/text/evaluate assertions. ' +
|
|
114
|
+
'No console/page errors is necessary but not sufficient to claim a logic fix. ' +
|
|
115
|
+
'Add waitForSelector, waitForText, or evaluate (DOM/read hooks) for stronger evidence.',
|
|
116
|
+
smokeStrength: 'weak',
|
|
117
|
+
}
|
|
118
|
+
: { smokeStrength: 'asserted' }),
|
|
70
119
|
});
|
|
71
120
|
},
|
|
72
121
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../src/cli/browser/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAuB,MAAM,sCAAsC,CAAC;AACpF,OAAO,EAAE,eAAe,EAA6C,MAAM,aAAa,CAAC;AAEzF,MAAM,YAAY,GAAG,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE;IAChD,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACnE,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;IACrF,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;IAClF,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../src/cli/browser/tools.ts"],"names":[],"mappings":"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"}
|