@petukhovart/agent-view 0.5.0 → 0.6.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/.claude-plugin/plugin.json +2 -2
- package/README.md +146 -48
- package/agents/design-conformance-runner.md +101 -0
- package/agents/verify-runner.md +97 -0
- package/package.json +2 -1
- package/skills/verify/SKILL.md +20 -0
- package/skills/verify-recipe/SKILL.md +18 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-view",
|
|
3
|
-
"description": "Visual verification CLI for desktop apps (Electron/Tauri/Browser) via Chrome DevTools Protocol. Ships two skills
|
|
4
|
-
"version": "0.
|
|
3
|
+
"description": "Visual verification CLI for desktop apps (Electron/Tauri/Browser) via Chrome DevTools Protocol. Ships two skills (verify, verify-recipe) and two Haiku-tier subagents (verify-runner, design-conformance-runner) so recipe execution and visual mockup-conformance run cheaply outside the main agent's context.",
|
|
4
|
+
"version": "0.6.0",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cdp",
|
|
7
7
|
"electron",
|
package/README.md
CHANGED
|
@@ -8,6 +8,16 @@ agent-view bridges that gap: it connects to any Chromium-based desktop app via C
|
|
|
8
8
|
|
|
9
9
|
Built for [Claude Code](https://docs.anthropic.com/en/docs/claude-code), but works with any AI agent or automation pipeline that can call CLI commands.
|
|
10
10
|
|
|
11
|
+
## 5-minute quickstart
|
|
12
|
+
|
|
13
|
+
1. **[Install](#install--update)** — `npm i -g @petukhovart/agent-view` plus the Claude Code plugin.
|
|
14
|
+
2. **[Enable CDP](#enabling-cdp) in your app** — one line in your Electron `main.ts`, gated to dev builds.
|
|
15
|
+
3. **`agent-view init`** in your project — then add `"allowEval": true` to the generated `agent-view.config.json`.
|
|
16
|
+
4. **`agent-view launch`** — starts your app and waits for CDP readiness.
|
|
17
|
+
5. **In Claude Code:** describe what you want verified — see [example prompts](#recommended-workflow-with-claude-code).
|
|
18
|
+
|
|
19
|
+
Each step links to the full explanation below.
|
|
20
|
+
|
|
11
21
|
## What it does
|
|
12
22
|
|
|
13
23
|
- **DOM accessibility tree** with ref IDs — compact, LLM-friendly, with text/role filters; `--compact` merges single-child chains for 40–60% fewer tokens, `--count` returns just the match count, `--max-lines` caps output, `--diff` emits only what changed since the last call
|
|
@@ -18,6 +28,9 @@ Built for [Claude Code](https://docs.anthropic.com/en/docs/claude-code), but wor
|
|
|
18
28
|
- **Console capture** — `console.log/warn/error` per page and per worker, with level/since filters and `--follow --until <pattern>` for early exit on a matching log
|
|
19
29
|
- **Worker access** — SharedWorker, ServiceWorker, dedicated Worker visible alongside pages; fuzzy `--target` resolution everywhere (id → title → URL)
|
|
20
30
|
- **Canvas / WebGL scene graph** — PixiJS today, engine-pluggable; `--compact` mirrors the DOM mode
|
|
31
|
+
- **Design-conformance verification** — pair screenshot commands with local design references (Figma export, hand-off
|
|
32
|
+
PNGs, any image on disk) inside a verify-recipe; the `design-conformance-runner` subagent reports visual deviations
|
|
33
|
+
against the mockup
|
|
21
34
|
|
|
22
35
|
## Why CLI, not MCP?
|
|
23
36
|
|
|
@@ -44,6 +57,9 @@ npm install -g @petukhovart/agent-view
|
|
|
44
57
|
|
|
45
58
|
The plugin ships two skills. **`verify`** executes visual and runtime checks against a running app. **`verify-recipe`** generates a `.claude/verify-recipes/<slug>.md` file — a disciplined, cheapest-first command sequence for a feature or bugfix — that you or any AI agent can run later. Trigger it with phrases like "write a verify-recipe for the login fix" or "generate a verification plan for this feature".
|
|
46
59
|
|
|
60
|
+
For Haiku-cost recipe execution and visual conformance against design mockups,
|
|
61
|
+
see [Recommended workflow with Claude Code](#recommended-workflow-with-claude-code) below.
|
|
62
|
+
|
|
47
63
|
Verify:
|
|
48
64
|
|
|
49
65
|
```bash
|
|
@@ -77,16 +93,18 @@ agent-view talks to your app over Chrome DevTools Protocol. Your app must be lau
|
|
|
77
93
|
|
|
78
94
|
### Recommended: in code (reliable, works with any build tool)
|
|
79
95
|
|
|
80
|
-
Add to your Electron main process:
|
|
96
|
+
Add to your Electron main process, **before `app.whenReady()`** (top of `main.ts`/`main.js`, right after the `electron` import — switches set after the app is ready are ignored):
|
|
81
97
|
|
|
82
98
|
```js
|
|
99
|
+
import { app } from 'electron';
|
|
100
|
+
|
|
83
101
|
app.commandLine.appendSwitch('remote-debugging-port', '9876');
|
|
84
102
|
```
|
|
85
103
|
|
|
86
104
|
> Any free port works — `9876` is just an example. Avoid `9222` (Chrome's own default remote-debugging port) to prevent
|
|
87
105
|
> collisions when Chrome is open.
|
|
88
106
|
|
|
89
|
-
|
|
107
|
+
**Production safety:** an open CDP port in a signed/notarized build is a remote-code-execution surface. Gate it on `!app.isPackaged` so it only opens in dev:
|
|
90
108
|
|
|
91
109
|
```js
|
|
92
110
|
if (!app.isPackaged) {
|
|
@@ -119,31 +137,142 @@ curl -s http://localhost:9876/json/version
|
|
|
119
137
|
|
|
120
138
|
If you see a JSON response with process info — you're good.
|
|
121
139
|
|
|
122
|
-
## Quick start
|
|
140
|
+
## Quick start with Claude Code (Prompting)
|
|
141
|
+
|
|
142
|
+
Assumes the plugin and CLI are installed (see [Install & Update](#install--update)) and CDP is enabled in your app (
|
|
143
|
+
see [Enabling CDP](#enabling-cdp)).
|
|
144
|
+
|
|
145
|
+
**1. Generate config once:**
|
|
123
146
|
|
|
124
147
|
```bash
|
|
125
148
|
cd your-electron-project
|
|
149
|
+
agent-view init # writes agent-view.config.json — auto-detects runtime, port, launch script, webgl engine
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Then open `agent-view.config.json` and add `"allowEval": true` if you want recipes to use `eval` / `watch` (most do —
|
|
153
|
+
store/state assertions are 100× cheaper than DOM scraping). Off by default for security; see [Config](#config) for the
|
|
154
|
+
full field list.
|
|
155
|
+
|
|
156
|
+
**2. Start your app:**
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
agent-view launch # uses the `launch` command from config, waits for CDP readiness, idempotent
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
(Or start it yourself with `npm run dev` etc. — `launch` is just a convenience.)
|
|
163
|
+
|
|
164
|
+
**3. From Claude Code, ask for a verification:**
|
|
165
|
+
|
|
166
|
+
```text
|
|
167
|
+
The "Save" button on the Settings dialog stayed enabled while a save was in flight.
|
|
168
|
+
I added a `saving` ref bound to :disabled. Verify it works:
|
|
169
|
+
- after click, button must be disabled until network completes
|
|
170
|
+
- no console errors in the flow
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Claude picks the `verify` skill, runs a handful of `eval` / `dom --filter` / `console` calls against your live app,
|
|
174
|
+
reports what passed and what failed. No CLI commands typed by you.
|
|
175
|
+
|
|
176
|
+
For a repeatable, multi-step verification (PRD/plan-driven, with optional design-mockup conformance),
|
|
177
|
+
see [Recommended workflow with Claude Code](#recommended-workflow-with-claude-code) — it's the canonical 3-phase prompt
|
|
178
|
+
flow this package is built around.
|
|
179
|
+
|
|
180
|
+
### Without Claude Code (manual CLI / CI / other agents)
|
|
181
|
+
|
|
182
|
+
If you're scripting from CI or another agent, the CLI works standalone:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
agent-view discover # List all windows (JSON)
|
|
186
|
+
agent-view dom --filter "Submit" # Accessibility tree, filtered, with ref IDs
|
|
187
|
+
agent-view fill 3 "hello@example.com"
|
|
188
|
+
agent-view click 7
|
|
189
|
+
agent-view eval "store.state.user.role"
|
|
190
|
+
agent-view screenshot --crop "Sidebar" --scale 0.5
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Full surface in [Commands](#commands) below.
|
|
194
|
+
|
|
195
|
+
## Recommended workflow with Claude Code
|
|
126
196
|
|
|
127
|
-
|
|
128
|
-
|
|
197
|
+
A repeatable, token-efficient flow for "I shipped a feature/fix → confirm it actually works visually and at runtime".
|
|
198
|
+
Three phases, each driven by a focused prompt.
|
|
129
199
|
|
|
130
|
-
|
|
131
|
-
agent-view launch
|
|
200
|
+
### Phase 1 — Author the verification plan (Opus / Sonnet)
|
|
132
201
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
agent-view dom # Accessibility tree with ref IDs
|
|
136
|
-
agent-view screenshot # PNG screenshot
|
|
202
|
+
Generate the recipe **once**, from a PRD / plan file / Jira ticket / commit range. The recipe is reusable — re-run after
|
|
203
|
+
every iteration on the same feature.
|
|
137
204
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
205
|
+
```text
|
|
206
|
+
Generate a verify-recipe for the changes in commits <hash1>..<hash2>.
|
|
207
|
+
Source plan: .claude/plans/2026-04-27-login-redirect.md
|
|
208
|
+
Original symptom: after login, redirect went to /home instead of /dashboard.
|
|
141
209
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
210
|
+
Design references (if any):
|
|
211
|
+
- /abs/path/figma-exports/login-success.png → label "post-login dashboard"
|
|
212
|
+
- /abs/path/figma-exports/error-state.png → label "invalid creds error"
|
|
145
213
|
```
|
|
146
214
|
|
|
215
|
+
What this triggers: the `verify-recipe` skill interviews you (if more context needed), then writes a
|
|
216
|
+
`.claude/verify-recipes/<slug>.md` with `Repro Steps`, `Evidence Commands` (cheapest-first: `eval` / `dom --filter`
|
|
217
|
+
before `screenshot`), `Regression Checks`, and — if you provided design refs — a `Design Conformance` table mapping
|
|
218
|
+
screenshot commands to expected reference images.
|
|
219
|
+
|
|
220
|
+
**Tip:** if you implemented from a Figma file via the `figma-implement-design` skill, it likely already saved exports
|
|
221
|
+
somewhere on disk — pass those paths. agent-view does NOT fetch from Figma URLs; provide local files only.
|
|
222
|
+
|
|
223
|
+
### Phase 2 — Run the recipe (delegated to Haiku)
|
|
224
|
+
|
|
225
|
+
```text
|
|
226
|
+
Run the verify-recipe at .claude/verify-recipes/<slug>.md.
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
What this triggers: the `verify` skill resolves the window via `agent-view discover`, then spawns the `verify-runner`
|
|
230
|
+
subagent (Haiku) to execute every step and return a compact JSON report. If the recipe has a `Design Conformance`
|
|
231
|
+
section, `design-conformance-runner` (also Haiku) runs in parallel and visually compares screenshots against the
|
|
232
|
+
references.
|
|
233
|
+
|
|
234
|
+
**Effect on cost:** raw output (DOM dumps, screenshots, eval values) stays in the subagent. The main agent only sees the
|
|
235
|
+
merged JSON report — typically <2k tokens vs ~50k if Opus ran the recipe directly.
|
|
236
|
+
|
|
237
|
+
### Phase 3 — Iterate on failures (Opus / Sonnet)
|
|
238
|
+
|
|
239
|
+
The merged report lists `failed`, `requires_visual_review`, and `major_mismatch` items with one-sentence diagnoses. Hand
|
|
240
|
+
any subset back to the main agent:
|
|
241
|
+
|
|
242
|
+
```text
|
|
243
|
+
Three steps failed in the verify run. Fix step 4 (zone filter not mutating store)
|
|
244
|
+
and step 7 (selective filter heading missing). Re-run only those two steps after the fix.
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
The main agent re-runs only the failing commands itself for richer evidence, makes the fix, and re-spawns
|
|
248
|
+
`verify-runner` for the targeted re-check — not the whole recipe.
|
|
249
|
+
|
|
250
|
+
### One-shot prompt (when there's no plan to convert)
|
|
251
|
+
|
|
252
|
+
For small fixes where you don't want a persistent recipe file:
|
|
253
|
+
|
|
254
|
+
```text
|
|
255
|
+
The "Save" button on the Settings dialog wasn't disabling while a save was in flight.
|
|
256
|
+
I added a `saving` ref and bound it to :disabled. Verify it works:
|
|
257
|
+
- after click, button must be disabled until network completes
|
|
258
|
+
- no console errors
|
|
259
|
+
- visual: button greys out (compare to /abs/path/saving-state.png if one is provided)
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Claude will pick the right skill (usually `verify` ad-hoc mode), run a handful of `eval` / `dom --filter` / `console`
|
|
263
|
+
calls, and only screenshot if the visual claim needs it.
|
|
264
|
+
|
|
265
|
+
### Anti-patterns to avoid
|
|
266
|
+
|
|
267
|
+
- "Just verify the feature" with no plan or symptom — the recipe author can't pick the cheapest signal without knowing
|
|
268
|
+
what "works" means. Give it the symptom that motivated the fix.
|
|
269
|
+
- Pasting Figma URLs and expecting agent-view to download them — it won't. Export the frames you care about to PNG
|
|
270
|
+
first.
|
|
271
|
+
- Running the recipe directly with Opus when a recipe file exists — that's exactly the case `verify-runner` is for.
|
|
272
|
+
Prefer Phase 2's prompt.
|
|
273
|
+
- Stuffing 50 assertions into one recipe — split per-feature. A recipe should run in <2 minutes and produce a report you
|
|
274
|
+
can read in 30 seconds.
|
|
275
|
+
|
|
147
276
|
## How it works
|
|
148
277
|
|
|
149
278
|
```
|
|
@@ -380,14 +509,6 @@ Output frames: `init` (baseline value), `diff` (RFC 6902 ops since last frame),
|
|
|
380
509
|
|
|
381
510
|
Stops the background lazy server.
|
|
382
511
|
|
|
383
|
-
## Output format
|
|
384
|
-
|
|
385
|
-
| Command | Format | Why |
|
|
386
|
-
|------------------------|------------|------------------------------|
|
|
387
|
-
| `dom`, `scene`, `snap` | Plain text | LLM-friendly, minimal tokens |
|
|
388
|
-
| `discover` | JSON | Machine-parseable |
|
|
389
|
-
| `screenshot` | File path | Agent reads the image |
|
|
390
|
-
|
|
391
512
|
## Performance
|
|
392
513
|
|
|
393
514
|
Built for tight `dom → click → dom` loops. Typical Electron app, ~200 AX nodes:
|
|
@@ -402,29 +523,6 @@ What makes it fast: 300ms AX-tree cache (invalidated on `click`/`fill`/navigatio
|
|
|
402
523
|
`[cache]`), parallel CDP calls in `click`, `Accessibility.queryAXTree` for filter lookups, and a single persistent CDP
|
|
403
524
|
WebSocket reused across commands (no relay).
|
|
404
525
|
|
|
405
|
-
## Example: testing a login flow
|
|
406
|
-
|
|
407
|
-
```bash
|
|
408
|
-
# Start the app
|
|
409
|
-
agent-view launch
|
|
410
|
-
|
|
411
|
-
# See the login page
|
|
412
|
-
agent-view dom --filter "login"
|
|
413
|
-
# RootWebArea "My App"
|
|
414
|
-
# textbox "Email" [ref=3]
|
|
415
|
-
# textbox "Password" [ref=5]
|
|
416
|
-
# button "Sign in" [ref=7]
|
|
417
|
-
|
|
418
|
-
# Fill credentials and submit
|
|
419
|
-
agent-view fill 3 "admin@example.com"
|
|
420
|
-
agent-view fill 5 "password123"
|
|
421
|
-
agent-view click 7
|
|
422
|
-
|
|
423
|
-
# Verify — did we land on the dashboard?
|
|
424
|
-
agent-view dom --depth 2
|
|
425
|
-
agent-view screenshot
|
|
426
|
-
```
|
|
427
|
-
|
|
428
526
|
## Troubleshooting
|
|
429
527
|
|
|
430
528
|
### CDP not responding
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: design-conformance-runner
|
|
3
|
+
description: Compares actual app screenshots against expected design reference images (from Figma exports, screenshots, or any local PNG/JPEG) and returns a JSON report of visual mismatches. Use when the user wants to verify design conformance, after a verify-runner reports a recipe with a Design Conformance section, or when explicitly asked to compare implementation vs mockup. Only works with LOCAL image files — does not fetch from Figma or any URL.
|
|
4
|
+
tools: Read, Bash, Glob
|
|
5
|
+
model: haiku
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
You are a focused visual diff executor. Your job: take pairs of (actual screenshot, expected reference image), inspect both, and report visual mismatches in a structured JSON report.
|
|
9
|
+
|
|
10
|
+
You are NOT a designer and NOT a recipe author. Do not redesign. Do not propose CSS fixes. Do not speculate about intent — describe what is visually different and let the parent agent decide what to do.
|
|
11
|
+
|
|
12
|
+
## Inputs you will receive
|
|
13
|
+
|
|
14
|
+
The parent agent will give you:
|
|
15
|
+
- `pairs` — list of `{ "label": "...", "actual_command_or_path": "agent-view screenshot ... | /abs/path/actual.png", "expected_path": "/abs/path/expected.png" }`
|
|
16
|
+
- `output_dir` — where to save captured screenshots (optional, default `.agent-view/verify-screenshots/`)
|
|
17
|
+
- `tolerance` — `strict | normal | loose` (optional, default `normal`)
|
|
18
|
+
|
|
19
|
+
If `actual_command_or_path` is a path that already exists, use it directly. If it is a `agent-view screenshot ...` command, run it (capturing the printed file path from stdout).
|
|
20
|
+
|
|
21
|
+
## Execution protocol
|
|
22
|
+
|
|
23
|
+
1. **Resolve every pair.** For each pair:
|
|
24
|
+
- If `expected_path` does not exist or is not readable → mark pair `skipped` with reason `expected_missing`.
|
|
25
|
+
- If `actual_command_or_path` is a command: run it via `Bash`, parse the output to get the saved screenshot path. If command fails, mark pair `failed` with the stderr.
|
|
26
|
+
- If `actual_command_or_path` is a path: verify it exists.
|
|
27
|
+
|
|
28
|
+
2. **Visually inspect both images.** Read each image with the `Read` tool (it returns image content for PNG/JPEG). For each pair, compare:
|
|
29
|
+
- **Layout**: relative position, alignment, spacing of major elements.
|
|
30
|
+
- **Sizing**: are the same components at proportional sizes?
|
|
31
|
+
- **Color**: do dominant colors match? Note significant deviations only — minor anti-aliasing differences are normal.
|
|
32
|
+
- **Typography**: font weight/size/family broadly match?
|
|
33
|
+
- **Content presence**: is anything visible in expected but missing in actual, or vice versa?
|
|
34
|
+
- **Visual decorations**: borders, shadows, dashed/solid lines, icons.
|
|
35
|
+
|
|
36
|
+
3. **Tolerance levels:**
|
|
37
|
+
- `strict` — flag any visible deviation.
|
|
38
|
+
- `normal` (default) — flag deviations a designer would notice in a code review (>5px misalignment, wrong color family, missing element, wrong icon).
|
|
39
|
+
- `loose` — only flag structural/content differences (missing elements, wrong layout, wrong components). Ignore color/spacing nuances.
|
|
40
|
+
|
|
41
|
+
4. **Do NOT:**
|
|
42
|
+
- Run pixel-level diff tools (you don't have them; the comparison is visual via your image-reading capability).
|
|
43
|
+
- Compare images that have radically different aspect ratios — note `aspect_ratio_mismatch` and skip detailed comparison.
|
|
44
|
+
- Compare across resolutions naively — if expected is 2× larger than actual, normalize mentally and only flag real differences.
|
|
45
|
+
- Speculate about CSS/code causes. Stick to visual observations.
|
|
46
|
+
|
|
47
|
+
## Output format
|
|
48
|
+
|
|
49
|
+
Return EXACTLY one fenced JSON block. No prose before or after.
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"started_at": "<ISO8601>",
|
|
54
|
+
"finished_at": "<ISO8601>",
|
|
55
|
+
"tolerance": "normal",
|
|
56
|
+
"summary": {
|
|
57
|
+
"total_pairs": 0,
|
|
58
|
+
"matches": 0,
|
|
59
|
+
"minor_mismatches": 0,
|
|
60
|
+
"major_mismatches": 0,
|
|
61
|
+
"skipped": 0,
|
|
62
|
+
"failed": 0
|
|
63
|
+
},
|
|
64
|
+
"pairs": [
|
|
65
|
+
{
|
|
66
|
+
"label": "<from input>",
|
|
67
|
+
"actual_path": "<resolved path>",
|
|
68
|
+
"expected_path": "<input path>",
|
|
69
|
+
"status": "match | minor_mismatch | major_mismatch | skipped | failed",
|
|
70
|
+
"deviations": [
|
|
71
|
+
{
|
|
72
|
+
"category": "layout | sizing | color | typography | content | decoration",
|
|
73
|
+
"severity": "minor | major",
|
|
74
|
+
"description": "<one sentence: what differs, where, by how much>",
|
|
75
|
+
"expected": "<short phrase>",
|
|
76
|
+
"actual": "<short phrase>"
|
|
77
|
+
}
|
|
78
|
+
],
|
|
79
|
+
"notes": "<optional, e.g. 'aspect ratio differs 16:9 vs 4:3 — comparison limited to top region'>"
|
|
80
|
+
}
|
|
81
|
+
],
|
|
82
|
+
"blocking_issues": [
|
|
83
|
+
"<empty if no major_mismatches; otherwise one line per major issue>"
|
|
84
|
+
]
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Severity rubric
|
|
89
|
+
|
|
90
|
+
- **major** — missing component, wrong component, broken layout (overlap/clipping), wrong color family (red where blue expected), text content differs.
|
|
91
|
+
- **minor** — spacing off by <10px, slight color shade difference, font weight off by 100, decorative detail (shadow blur, dashed vs dotted line) differs.
|
|
92
|
+
- **match** — within tolerance, no notable deviation worth reporting.
|
|
93
|
+
|
|
94
|
+
A pair with at least one `major` deviation has status `major_mismatch`. A pair with only `minor` deviations has status `minor_mismatch`. No deviations → `match`.
|
|
95
|
+
|
|
96
|
+
## Boundaries
|
|
97
|
+
|
|
98
|
+
- Never write code. Never suggest CSS values. Never edit files other than to save screenshots.
|
|
99
|
+
- If parent agent passes 0 pairs, return summary with all zeros and `blocking_issues: ["no pairs provided"]`.
|
|
100
|
+
- If all `expected_path`s are missing, return all `skipped` and a clear `blocking_issues` entry — the parent likely needs to ask the user for design refs.
|
|
101
|
+
- Token discipline: you run on Haiku. The JSON is the deliverable. Don't narrate.
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: verify-runner
|
|
3
|
+
description: Executes a pre-authored agent-view verify recipe (`.claude/verify-recipes/<slug>.md`) against a running app and returns a compact JSON report. Use when the user wants to run a verify recipe, verify a shipped feature/fix against a recipe file, or when the verify skill delegates execution. Does NOT author recipes — for that, use the verify-recipe skill.
|
|
4
|
+
tools: Read, Bash, Glob
|
|
5
|
+
model: haiku
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
You are a disciplined recipe executor. Your only job: take a verify-recipe markdown file, execute its commands against a running app via `agent-view`, compare results to the `Expected:` lines, and return a compact JSON report.
|
|
9
|
+
|
|
10
|
+
You are NOT a debugger and NOT a recipe author. Do not propose fixes. Do not invent extra checks. Do not rewrite the recipe. Execute exactly what is written, report exactly what you observed.
|
|
11
|
+
|
|
12
|
+
## Inputs you will receive
|
|
13
|
+
|
|
14
|
+
The parent agent will give you:
|
|
15
|
+
- `recipe_path` — absolute path to the recipe file (required)
|
|
16
|
+
- `window_id` — value to substitute for `$W` in commands (optional; if recipe needs it and not provided, run `agent-view discover` once and pick the main window)
|
|
17
|
+
- `extra_context` — anything else relevant (optional)
|
|
18
|
+
|
|
19
|
+
## Execution protocol
|
|
20
|
+
|
|
21
|
+
1. **Read the recipe** with `Read`. Parse:
|
|
22
|
+
- The `## Repro Steps` section — these are preconditions, NOT commands you run. If the app state cannot be confirmed (e.g., command in step 0 fails), report `precondition_failed` and stop.
|
|
23
|
+
- The `## Evidence Commands` section — numbered subsections, each with one or more `agent-view` commands inside a fenced bash block, followed by an `Expected:` line.
|
|
24
|
+
- The `## Design Conformance` section — if present, IGNORE IT. Design comparison is the design-conformance-runner's job. Note its presence in the report (`design_conformance_section: true`) so the parent agent can spawn that runner.
|
|
25
|
+
|
|
26
|
+
2. **Substitute placeholders.** Replace `$W` with the provided `window_id`. If a command refers to a `<ref>` placeholder that depends on output of a previous step (`<email-ref>` etc.), resolve it by parsing the previous `dom` output for the matching node and use the printed `[ref=N]` value. If you cannot resolve a ref, mark that step `failed` with reason `unresolvable_ref` and continue.
|
|
27
|
+
|
|
28
|
+
3. **Run each command** with `Bash`. Use a generous timeout (60s default). Capture stdout, stderr, and exit code.
|
|
29
|
+
|
|
30
|
+
4. **Compare to `Expected:`.** The recipe author writes the expected criterion in plain English following the bash block. Decide pass/fail by literal match where possible:
|
|
31
|
+
- Numeric criterion (`> 0`, `=== 5`, `< 1000`) → parse the actual value and evaluate.
|
|
32
|
+
- String/JSON criterion → substring or shape match.
|
|
33
|
+
- "Empty" / "(no console messages)" → output is empty or matches the literal phrase.
|
|
34
|
+
- Visual criterion ("dashed outlines", "neutral-gray") → mark as `requires_visual_review` (you don't see pixels), record the screenshot path, do not pass or fail.
|
|
35
|
+
- Ambiguous English ("looks correct") → mark as `subjective`, do not pass or fail.
|
|
36
|
+
|
|
37
|
+
5. **Do not retry on failure** beyond what the recipe explicitly says. One try per command. If a command crashes (non-zero exit, error output), record it as `failed` with the captured stderr and move on.
|
|
38
|
+
|
|
39
|
+
6. **Stop conditions:**
|
|
40
|
+
- `precondition_failed` (recipe-required state not present) → stop, report what you have.
|
|
41
|
+
- `cdp_disconnected` (`agent-view discover` returns nothing mid-run) → stop, report.
|
|
42
|
+
- Otherwise: run every step in the recipe, even after failures.
|
|
43
|
+
|
|
44
|
+
## Output format
|
|
45
|
+
|
|
46
|
+
Return EXACTLY one fenced JSON block. No prose before or after.
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"recipe_path": "<path>",
|
|
51
|
+
"recipe_title": "<from H1>",
|
|
52
|
+
"started_at": "<ISO8601>",
|
|
53
|
+
"finished_at": "<ISO8601>",
|
|
54
|
+
"window_id": "<resolved>",
|
|
55
|
+
"design_conformance_section": false,
|
|
56
|
+
"design_conformance_pairs": [],
|
|
57
|
+
"summary": {
|
|
58
|
+
"total": 0,
|
|
59
|
+
"passed": 0,
|
|
60
|
+
"failed": 0,
|
|
61
|
+
"requires_visual_review": 0,
|
|
62
|
+
"subjective": 0,
|
|
63
|
+
"skipped": 0
|
|
64
|
+
},
|
|
65
|
+
"steps": [
|
|
66
|
+
{
|
|
67
|
+
"index": 1,
|
|
68
|
+
"title": "<from ### heading>",
|
|
69
|
+
"status": "passed | failed | requires_visual_review | subjective | skipped",
|
|
70
|
+
"commands": ["agent-view ..."],
|
|
71
|
+
"expected": "<verbatim from recipe>",
|
|
72
|
+
"actual": "<truncated stdout, max 500 chars; full output too verbose>",
|
|
73
|
+
"stderr": "<only if non-empty, max 200 chars>",
|
|
74
|
+
"diagnosis": "<one sentence: why it failed, or 'matched expected', or 'requires human review of <screenshot path>'>"
|
|
75
|
+
}
|
|
76
|
+
],
|
|
77
|
+
"regression_checks": [
|
|
78
|
+
{ "criterion": "...", "status": "passed | failed | skipped", "evidence": "..." }
|
|
79
|
+
],
|
|
80
|
+
"blocking_issues": [
|
|
81
|
+
"<one-line summary of each failed/precondition_failed item — empty array if all good>"
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
If `design_conformance_section: true`, also extract the screenshot↔reference pairs from that section and put them in `design_conformance_pairs` as `[{ "step_label": "...", "screenshot_command": "agent-view screenshot ...", "expected_ref_path": "..." }]`. The parent agent will hand these to the design runner.
|
|
87
|
+
|
|
88
|
+
## Boundaries
|
|
89
|
+
|
|
90
|
+
- Don't suggest code fixes. The `diagnosis` field is one sentence describing the observation only ("returned 0, expected > 0", "command exited 1: cdp connection refused"). Never write "you should change X".
|
|
91
|
+
- Don't take screenshots not in the recipe. Don't add `eval` calls not in the recipe. Don't open extra DOM views to "investigate". Recipe is the contract.
|
|
92
|
+
- Truncate large outputs aggressively. The parent agent only needs enough to understand pass/fail and re-investigate if needed — it can re-run the command itself.
|
|
93
|
+
- If the recipe is malformed (no `## Evidence Commands` section, no fenced blocks), return a JSON report with `summary.total: 0` and `blocking_issues: ["recipe malformed: <reason>"]`.
|
|
94
|
+
|
|
95
|
+
## Token discipline
|
|
96
|
+
|
|
97
|
+
You are running on Haiku to save the parent agent's context. Make every output line earn its place. The JSON report is the deliverable — anything you print outside the JSON is wasted tokens.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@petukhovart/agent-view",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "CLI tool for visual verification of desktop apps (Electron/Tauri) via Chrome DevTools Protocol",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"dist",
|
|
12
12
|
".claude-plugin",
|
|
13
13
|
"skills",
|
|
14
|
+
"agents",
|
|
14
15
|
"README.md",
|
|
15
16
|
"LICENSE"
|
|
16
17
|
],
|
package/skills/verify/SKILL.md
CHANGED
|
@@ -178,6 +178,26 @@ When two tools could answer the same question, prefer the one higher up the tabl
|
|
|
178
178
|
|
|
179
179
|
## Verification Workflow
|
|
180
180
|
|
|
181
|
+
### Recipe Execution Mode (preferred when a recipe exists)
|
|
182
|
+
|
|
183
|
+
If the developer points you at a `.claude/verify-recipes/<slug>.md` file, OR you discover one matching the current task via `ls .claude/verify-recipes/`, **delegate execution to the `verify-runner` subagent** instead of running commands yourself.
|
|
184
|
+
|
|
185
|
+
Why: recipe execution is mechanical (run commands, compare to `Expected:`, report). It does not need Opus-level reasoning, but the raw output (DOM dumps, screenshots, eval results) easily exceeds 30k tokens of context noise. Delegating to a Haiku subagent keeps your context clean and cuts cost ~10×.
|
|
186
|
+
|
|
187
|
+
How to delegate:
|
|
188
|
+
|
|
189
|
+
1. Resolve the window id once: `agent-view discover` → pick the main window's id.
|
|
190
|
+
2. Spawn `verify-runner` via the Agent tool with a prompt containing:
|
|
191
|
+
- Absolute `recipe_path`
|
|
192
|
+
- Resolved `window_id`
|
|
193
|
+
- Any extra context (e.g. "user is already logged in", "GIS widget already mounted")
|
|
194
|
+
3. Wait for the JSON report. Read `summary`, `blocking_issues`, and any `failed` step diagnoses.
|
|
195
|
+
4. **If `design_conformance_section: true`** in the report: also spawn `design-conformance-runner` in parallel, passing the `design_conformance_pairs` array. Merge both reports before answering the user.
|
|
196
|
+
5. For `requires_visual_review` steps that have no design ref attached: open the screenshot yourself with `Read` and decide pass/fail.
|
|
197
|
+
6. For `failed` steps: re-run the specific failing command yourself if you need richer evidence to diagnose. Do not re-execute the whole recipe.
|
|
198
|
+
|
|
199
|
+
Output to the user: a tight summary — what passed, what failed, what needs visual review, and (if any) which design conformance issues to fix. Do not paste the raw JSON unless asked.
|
|
200
|
+
|
|
181
201
|
### Ad-hoc Mode (standalone)
|
|
182
202
|
|
|
183
203
|
After making code changes:
|
|
@@ -48,7 +48,8 @@ Pick the first row that can answer the question. Only go lower when the row abov
|
|
|
48
48
|
- Opening with a screenshot to "see the state" — use `dom --filter` or `eval` first
|
|
49
49
|
- Using `eval` when `dom --filter` answers the question
|
|
50
50
|
- Assertions that depend on transient state without `watch --until` to stabilize first
|
|
51
|
-
- "Check that it looks right" — every assertion must be a concrete pass/fail criterion
|
|
51
|
+
- "Check that it looks right" — every assertion must be a concrete pass/fail criterion. The single legitimate exception is the `## Design Conformance` section, which delegates visual judgment to the design-conformance-runner subagent against an explicit reference image.
|
|
52
|
+
- Inventing design reference paths (`.figma-refs/...`, `assets/mockups/...`) when the developer did not provide them. No refs → no Design Conformance section.
|
|
52
53
|
|
|
53
54
|
## Workflow
|
|
54
55
|
|
|
@@ -59,9 +60,12 @@ When invoked, ask the developer in plain text (no tool calls yet):
|
|
|
59
60
|
1. What was shipped or fixed? (feature name or bug description)
|
|
60
61
|
2. What was the original symptom or expected behavior?
|
|
61
62
|
3. Any known failure mode or edge case to cover?
|
|
63
|
+
4. (Optional) Are there design reference images to verify against? If yes — local path, glob, or list of files. **Only local files are supported.**
|
|
62
64
|
|
|
63
65
|
Wait for the response before continuing.
|
|
64
66
|
|
|
67
|
+
If the user provides design refs in step 4, store them for Step 2's optional `Design Conformance` section. If not provided, skip that section entirely — never invent a path or assume a convention.
|
|
68
|
+
|
|
65
69
|
### Step 2 — draft the recipe
|
|
66
70
|
|
|
67
71
|
Use the answers to produce a recipe with these sections:
|
|
@@ -98,6 +102,19 @@ Cost: ~<N> tokens
|
|
|
98
102
|
## Regression Checks
|
|
99
103
|
- [ ] <adjacent flow> — `agent-view <command>` → `<expected>`
|
|
100
104
|
|
|
105
|
+
## Design Conformance
|
|
106
|
+
<!-- INCLUDE THIS SECTION ONLY IF the developer provided design refs in Step 1 question 4. -->
|
|
107
|
+
<!-- Each pair: a screenshot command + an absolute path to the expected reference image. -->
|
|
108
|
+
<!-- The design-conformance-runner subagent reads this section, runs the screenshot commands, and visually compares against the expected refs. -->
|
|
109
|
+
<!-- Do NOT invent design ref paths. Do NOT assume a convention (e.g. .figma-refs/). Use exactly what the developer provided. -->
|
|
110
|
+
|
|
111
|
+
| Step Label | Screenshot Command | Expected Reference |
|
|
112
|
+
|---|---|---|
|
|
113
|
+
| <area name e.g. "filter panel"> | `agent-view screenshot --crop "<area>" --scale 0.5` | `<absolute path to expected PNG/JPEG>` |
|
|
114
|
+
| <area name> | `agent-view screenshot --window $W --scale 0.5` | `<absolute path>` |
|
|
115
|
+
|
|
116
|
+
Tolerance: `normal` (default — flag deviations a designer would notice in code review). Use `loose` only if the developer says exact pixel parity is not required.
|
|
117
|
+
|
|
101
118
|
## Anti-patterns avoided
|
|
102
119
|
- <note any recipe-specific traps, e.g. "state resets on reload — watch needed before dom check">
|
|
103
120
|
```
|