verikun 0.7.0 → 0.8.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/README.md +12 -0
- package/dist/agent/engine.js +18 -0
- package/dist/agent/grammar.js +6 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -232,6 +232,11 @@ a hard iteration cap and stop early if the screen stops changing.
|
|
|
232
232
|
- An `ai` run records like any other flow, so it produces the same JUnit + HTML report —
|
|
233
233
|
with the cost line and any **suggested test improvements** (workarounds the model
|
|
234
234
|
applied, which you can fold back into the prose to stabilize the test and cut tokens).
|
|
235
|
+
- **Review screenshots are inserted automatically.** The compiler adds `screenshot` steps
|
|
236
|
+
around transitions and inside loops, so the report carries a before/after visual trail
|
|
237
|
+
for post-run review. They are dumped for humans, never read back by the model (no token
|
|
238
|
+
cost on replay), and never gate the test — a capture that hiccups is logged and skipped,
|
|
239
|
+
not a failure.
|
|
235
240
|
|
|
236
241
|
## Suites — run a directory of tests
|
|
237
242
|
|
|
@@ -424,6 +429,13 @@ safely resample (palette, 16-bit, interlaced) are written through untouched, so
|
|
|
424
429
|
screenshot is never corrupted — only sometimes left full-size (noted on stderr).
|
|
425
430
|
Failure-evidence captures in test-run reports stay full-resolution for debugging.
|
|
426
431
|
|
|
432
|
+
**Read-back vs evidence.** The downscaling above matters when an agent *reads a
|
|
433
|
+
screenshot back into its context* to decide the next action — that is the token cost to
|
|
434
|
+
manage. A screenshot taken purely as **report evidence and never read back** costs nothing
|
|
435
|
+
at runtime, so driving a flow to a report should capture liberally around transitions.
|
|
436
|
+
`vk ai` does this automatically (see [AI](#ai--natural-language-tests)); when driving by
|
|
437
|
+
hand, `vk screenshot` around each screen change and leave the PNG in the report.
|
|
438
|
+
|
|
427
439
|
## How it works
|
|
428
440
|
|
|
429
441
|
```
|
package/dist/agent/engine.js
CHANGED
|
@@ -8,6 +8,11 @@ const ir_1 = require("./ir");
|
|
|
8
8
|
const describe = (leaf) => [leaf.command, ...leaf.positionals, ...leaf.flags.map((f) => (f.value === 'true' ? `--${f.name}` : `--${f.name} ${f.value}`))]
|
|
9
9
|
.join(' ')
|
|
10
10
|
.trim();
|
|
11
|
+
/** A screenshot leaf is best-effort review evidence, not a gate. The `vk ai`
|
|
12
|
+
* grammar has the model sprinkle them around transitions, so a capture that
|
|
13
|
+
* fails (a device hiccup on screencap) must never turn a green run red — see
|
|
14
|
+
* the guard in execLeaf. */
|
|
15
|
+
const isScreenshotLeaf = (leaf) => leaf.command === 'screenshot' || leaf.command === 'shot';
|
|
11
16
|
/** A structural fingerprint of the screen: sorted id+text+type set. Used for the
|
|
12
17
|
* loop no-progress check — deliberately NOT the raw hierarchy (its node ordering
|
|
13
18
|
* is nondeterministic between identical states, which would false-trip). */
|
|
@@ -129,6 +134,19 @@ async function runPlan(plan, deps) {
|
|
|
129
134
|
}
|
|
130
135
|
if (outcome.code === 0)
|
|
131
136
|
return { status: 'ok' };
|
|
137
|
+
// A review screenshot is best-effort evidence, never a gate. The grammar has the
|
|
138
|
+
// model insert them liberally around transitions, so a capture that fails (a
|
|
139
|
+
// device hiccup on screencap) must not fail an otherwise-green run. Log it,
|
|
140
|
+
// downgrade the just-recorded failed step to a clean pass (markLastStepHealed
|
|
141
|
+
// sets status=passed/exitCode=0 and drops the failure evidence) so the report and
|
|
142
|
+
// JUnit stay consistent with the green run, then continue. Scoped to screenshot/
|
|
143
|
+
// shot — every other command's failure stays terminal.
|
|
144
|
+
if (isScreenshotLeaf(current)) {
|
|
145
|
+
const why = outcome.error ? outcome.error.message.split('\n')[0] : `exited ${outcome.code}`;
|
|
146
|
+
deps.log(`[ai] ${where}: screenshot capture failed (${why}) — continuing (best-effort review screenshot)`);
|
|
147
|
+
deps.markHealed?.(`screenshot capture failed (${why}) — skipped (best-effort)`);
|
|
148
|
+
return { status: 'ok' };
|
|
149
|
+
}
|
|
132
150
|
if (isHealable(outcome)) {
|
|
133
151
|
return { status: 'fail', where, reason: `unresolved after ${maxRepairs} repair attempt(s): ${outcome.error.message.split('\n')[0]}` };
|
|
134
152
|
}
|
package/dist/agent/grammar.js
CHANGED
|
@@ -54,7 +54,12 @@ RULES:
|
|
|
54
54
|
- assert is for VERIFICATION only and is terminal — never use it as a step you expect to
|
|
55
55
|
fail. Put genuinely-optional UI behind if-present.
|
|
56
56
|
- Prefer resource-id / accessibility selectors over visible text where possible.
|
|
57
|
-
- Translate the test literally and minimally
|
|
57
|
+
- Translate the test literally and minimally: do not invent ACTION steps (tap/text/swipe/key/assert)
|
|
58
|
+
the prose does not imply. The ONE exception is screenshot — insert screenshot steps liberally as
|
|
59
|
+
post-run review evidence: after each screen transition (launch, a navigation tap, a submit, a
|
|
60
|
+
swipe/scroll) AND inside if-present/repeat bodies, so a failing branch or loop iteration is visible
|
|
61
|
+
in the report. Screenshots never affect the result; err toward too many. They are dumped into the
|
|
62
|
+
report for humans and never read back, so they are free on replay.`;
|
|
58
63
|
exports.REPAIR_GRAMMAR = `A single step in a verikun plan failed to resolve its selector against the live screen
|
|
59
64
|
(shown below). Decide between two outcomes — and be STRICT:
|
|
60
65
|
|
package/dist/version.js
CHANGED
|
@@ -3,4 +3,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.VERSION = void 0;
|
|
4
4
|
// GENERATED by scripts/gen-version.mjs from package.json's "version" at build time
|
|
5
5
|
// (the `prebuild` script). Do NOT edit by hand; bump package.json instead.
|
|
6
|
-
exports.VERSION = '0.
|
|
6
|
+
exports.VERSION = '0.8.0';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "verikun",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Drive Android emulators/devices and iOS simulators for AI agents: tap, type, swipe, screenshot, and inspect the UI hierarchy by semantic identifiers — like Puppeteer for native apps.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"android",
|