@petukhovart/agent-view 0.1.0 → 0.5.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/marketplace.json +14 -0
- package/.claude-plugin/plugin.json +13 -2
- package/README.md +211 -61
- package/dist/adapters/browser.d.ts.map +1 -1
- package/dist/adapters/browser.js +11 -11
- package/dist/adapters/browser.js.map +1 -1
- package/dist/adapters/electron.d.ts.map +1 -1
- package/dist/adapters/electron.js +11 -11
- package/dist/adapters/electron.js.map +1 -1
- package/dist/adapters/tauri.d.ts.map +1 -1
- package/dist/adapters/tauri.js +11 -11
- package/dist/adapters/tauri.js.map +1 -1
- package/dist/adapters/types.d.ts +5 -2
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/cdp/_tests/console-stream.d.ts +35 -0
- package/dist/cdp/_tests/console-stream.d.ts.map +1 -0
- package/dist/cdp/_tests/console-stream.js +103 -0
- package/dist/cdp/_tests/console-stream.js.map +1 -0
- package/dist/cdp/ax-cache.d.ts +16 -0
- package/dist/cdp/ax-cache.d.ts.map +1 -0
- package/dist/cdp/ax-cache.js +31 -0
- package/dist/cdp/ax-cache.js.map +1 -0
- package/dist/cdp/console-stream.d.ts +35 -0
- package/dist/cdp/console-stream.d.ts.map +1 -0
- package/dist/cdp/console-stream.js +103 -0
- package/dist/cdp/console-stream.js.map +1 -0
- package/dist/cdp/transport.d.ts +5 -2
- package/dist/cdp/transport.d.ts.map +1 -1
- package/dist/cdp/transport.js +309 -26
- package/dist/cdp/transport.js.map +1 -1
- package/dist/cdp/types.d.ts +109 -8
- package/dist/cdp/types.d.ts.map +1 -1
- package/dist/cdp/types.js +35 -1
- package/dist/cdp/types.js.map +1 -1
- package/dist/cli/commands/console.d.ts +12 -0
- package/dist/cli/commands/console.d.ts.map +1 -0
- package/dist/cli/commands/console.js +32 -0
- package/dist/cli/commands/console.js.map +1 -0
- package/dist/cli/commands/dom.d.ts +5 -0
- package/dist/cli/commands/dom.d.ts.map +1 -1
- package/dist/cli/commands/dom.js +5 -0
- package/dist/cli/commands/dom.js.map +1 -1
- package/dist/cli/commands/drag.d.ts +13 -0
- package/dist/cli/commands/drag.d.ts.map +1 -0
- package/dist/cli/commands/drag.js +72 -0
- package/dist/cli/commands/drag.js.map +1 -0
- package/dist/cli/commands/eval.d.ts +9 -0
- package/dist/cli/commands/eval.d.ts.map +1 -0
- package/dist/cli/commands/eval.js +30 -0
- package/dist/cli/commands/eval.js.map +1 -0
- package/dist/cli/commands/scene.d.ts +1 -0
- package/dist/cli/commands/scene.d.ts.map +1 -1
- package/dist/cli/commands/scene.js +2 -0
- package/dist/cli/commands/scene.js.map +1 -1
- package/dist/cli/commands/screenshot.d.ts +2 -0
- package/dist/cli/commands/screenshot.d.ts.map +1 -1
- package/dist/cli/commands/screenshot.js +6 -0
- package/dist/cli/commands/screenshot.js.map +1 -1
- package/dist/cli/commands/snap.d.ts +1 -0
- package/dist/cli/commands/snap.d.ts.map +1 -1
- package/dist/cli/commands/snap.js +2 -0
- package/dist/cli/commands/snap.js.map +1 -1
- package/dist/cli/commands/targets.d.ts +7 -0
- package/dist/cli/commands/targets.d.ts.map +1 -0
- package/dist/cli/commands/targets.js +30 -0
- package/dist/cli/commands/targets.js.map +1 -0
- package/dist/cli/commands/watch.d.ts +12 -0
- package/dist/cli/commands/watch.d.ts.map +1 -0
- package/dist/cli/commands/watch.js +233 -0
- package/dist/cli/commands/watch.js.map +1 -0
- package/dist/cli/index.js +86 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/config/manager.d.ts.map +1 -1
- package/dist/config/manager.js +11 -1
- package/dist/config/manager.js.map +1 -1
- package/dist/config/types.d.ts +11 -3
- package/dist/config/types.d.ts.map +1 -1
- package/dist/inspectors/dom/index.d.ts +30 -0
- package/dist/inspectors/dom/index.d.ts.map +1 -0
- package/dist/inspectors/dom/index.js +283 -0
- package/dist/inspectors/dom/index.js.map +1 -0
- package/dist/inspectors/scene/adapters/pixi/adapter.d.ts +3 -0
- package/dist/inspectors/scene/adapters/pixi/adapter.d.ts.map +1 -0
- package/dist/inspectors/scene/adapters/pixi/adapter.js +51 -0
- package/dist/inspectors/scene/adapters/pixi/adapter.js.map +1 -0
- package/dist/inspectors/scene/adapters/pixi/index.d.ts +2 -0
- package/dist/inspectors/scene/adapters/pixi/index.d.ts.map +1 -0
- package/dist/inspectors/scene/adapters/pixi/index.js +2 -0
- package/dist/inspectors/scene/adapters/pixi/index.js.map +1 -0
- package/dist/inspectors/scene/adapters/pixi/injection.d.ts +39 -0
- package/dist/inspectors/scene/adapters/pixi/injection.d.ts.map +1 -0
- package/dist/inspectors/scene/adapters/pixi/injection.js +41 -0
- package/dist/inspectors/scene/adapters/pixi/injection.js.map +1 -0
- package/dist/inspectors/scene/formatter.d.ts +0 -1
- package/dist/inspectors/scene/formatter.d.ts.map +1 -1
- package/dist/inspectors/scene/formatter.js +100 -43
- package/dist/inspectors/scene/formatter.js.map +1 -1
- package/dist/inspectors/scene/index.d.ts +4 -4
- package/dist/inspectors/scene/index.d.ts.map +1 -1
- package/dist/inspectors/scene/index.js +8 -5
- package/dist/inspectors/scene/index.js.map +1 -1
- package/dist/inspectors/scene/pixi.js.map +1 -1
- package/dist/inspectors/scene/registry.d.ts +2 -2
- package/dist/inspectors/scene/registry.d.ts.map +1 -1
- package/dist/inspectors/scene/registry.js +8 -8
- package/dist/inspectors/scene/registry.js.map +1 -1
- package/dist/inspectors/scene/types.d.ts +6 -10
- package/dist/inspectors/scene/types.d.ts.map +1 -1
- package/dist/inspectors/watch/index.d.ts +18 -0
- package/dist/inspectors/watch/index.d.ts.map +1 -0
- package/dist/inspectors/watch/index.js +39 -0
- package/dist/inspectors/watch/index.js.map +1 -0
- package/dist/inspectors/watch/types.d.ts +70 -0
- package/dist/inspectors/watch/types.d.ts.map +1 -0
- package/dist/inspectors/watch/types.js +21 -0
- package/dist/inspectors/watch/types.js.map +1 -0
- package/dist/server/server.d.ts +31 -1
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +620 -67
- package/dist/server/server.js.map +1 -1
- package/dist/server/watch-session.d.ts +32 -0
- package/dist/server/watch-session.d.ts.map +1 -0
- package/dist/server/watch-session.js +165 -0
- package/dist/server/watch-session.js.map +1 -0
- package/dist/types.d.ts +4 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -1
- package/package.json +61 -59
- package/skills/verify/SKILL.md +146 -11
- package/skills/verify-recipe/SKILL.md +185 -0
package/skills/verify/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: verify
|
|
3
|
-
description: "Visual verification of desktop
|
|
3
|
+
description: "Visual + runtime verification of desktop apps via Chrome DevTools Protocol. Use when modifying UI components, fixing visual bugs, testing user interactions, verifying layout, or when any workflow phase needs to inspect the running application — DOM, screenshots, scene graph, runtime state in pages and SharedWorkers/ServiceWorkers, console errors, or reactive-state diffs over time. Triggers on: verify, check UI, test how it looks, visual regression, screenshot, inspect DOM, check store/state, watch state changes, what changed after click, wait until state, read worker, console errors, runtime check, eval in page."
|
|
4
4
|
allowed-tools: Bash(agent-view *)
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -12,7 +12,7 @@ You have access to `agent-view` CLI for inspecting and interacting with desktop
|
|
|
12
12
|
|
|
13
13
|
The target project must have:
|
|
14
14
|
1. `agent-view.config.json` in project root (run `agent-view init` to generate)
|
|
15
|
-
2. CDP enabled in the app (e.g. `--remote-debugging-port=
|
|
15
|
+
2. CDP enabled in the app (e.g. `--remote-debugging-port=9876` for Electron — avoid `9222`, it's Chrome's own default and collides when Chrome is open)
|
|
16
16
|
|
|
17
17
|
If config is missing, run `agent-view init` first.
|
|
18
18
|
|
|
@@ -31,22 +31,119 @@ agent-view dom # DOM accessibility tree (default window
|
|
|
31
31
|
agent-view dom --window <id|name> # Specific window
|
|
32
32
|
agent-view dom --filter "button" # Filter by text/role
|
|
33
33
|
agent-view dom --depth 3 # Limit tree depth
|
|
34
|
+
agent-view dom --compact # Merge single-child chains onto one line (~40-60% fewer tokens)
|
|
35
|
+
agent-view dom --count # Count of all visible nodes (single integer line)
|
|
36
|
+
agent-view dom --filter "row" --count # Count matching nodes — e.g. "does this table have 5 rows?"
|
|
37
|
+
agent-view dom --max-lines 200 # Hard line budget; refs for truncated nodes still stored
|
|
38
|
+
agent-view dom --diff # Lines changed since last dom call (+ added / - removed)
|
|
34
39
|
```
|
|
35
40
|
|
|
41
|
+
`--count` skips tree output and ref mutations — cheapest way to assert "element exists N times" without loading the full tree into context.
|
|
42
|
+
|
|
36
43
|
### Interaction
|
|
37
44
|
```bash
|
|
38
45
|
agent-view click <ref> # Click element by ref from dom output
|
|
39
46
|
agent-view click --pos 100,200 # Click by coordinates (for canvas)
|
|
40
47
|
agent-view fill <ref> "text" # Type into input field
|
|
48
|
+
agent-view drag --from <ref> --to <ref> # Drag element to another element by ref
|
|
49
|
+
agent-view drag --from-pos 50,80 --to-pos 200,300 # Drag by coordinates (for canvas / Pixi)
|
|
50
|
+
agent-view drag --from <ref> --to <ref> --steps 25 --hold-ms 60 # Smoother movement, longer hold
|
|
41
51
|
```
|
|
42
52
|
|
|
53
|
+
`drag` dispatches `mousePressed` → N × `mouseMoved` → `mouseReleased` via CDP. Endpoints can mix
|
|
54
|
+
ref and coordinate (e.g. `--from <ref> --to-pos 400,300`). For canvas/Pixi targets always use
|
|
55
|
+
`--from-pos`/`--to-pos` — derive the centroid via `agent-view eval` from the scene graph.
|
|
56
|
+
Refs are resolved fresh on each call, so window resizes between snapshots are tolerated.
|
|
57
|
+
Increase `--steps` for handlers using `globalpointermove` so intermediate frames are not skipped.
|
|
58
|
+
|
|
43
59
|
### Screenshots
|
|
44
60
|
```bash
|
|
45
|
-
agent-view screenshot
|
|
46
|
-
agent-view screenshot --window <id>
|
|
61
|
+
agent-view screenshot --scale 0.5 # Recommended: JPEG at half-res (~3× fewer vision tokens)
|
|
62
|
+
agent-view screenshot --scale 0.5 --window <id> # Specific window
|
|
63
|
+
agent-view screenshot --crop "Sidebar" # Crop to element bounding box (~1.6k tokens — 12× win)
|
|
64
|
+
agent-view screenshot --crop "Chart" --scale 0.5 # Crop + scale (stacks)
|
|
65
|
+
agent-view screenshot # Full-res PNG (expensive: ~19k tokens at 1920×1080)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
`--crop <filter>` resolves the element with the same filter syntax as `dom --filter`, then crops the screenshot to its bounding box. Prefer `--crop` over full-window screenshots whenever you only need to inspect a specific section. Falls back to full-window with a stderr warning if the filter matches nothing.
|
|
69
|
+
|
|
70
|
+
### Runtime State (`eval`)
|
|
71
|
+
|
|
72
|
+
Reads runtime values DOM/screenshot can't reveal — store contents, computed flags, worker internals.
|
|
73
|
+
**Requires `"allowEval": true` in `agent-view.config.json`** — if the call returns "eval is disabled", tell the user to add the flag rather than working around it.
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
agent-view eval "store.state.user.role" # default page target
|
|
77
|
+
agent-view eval --window "Settings" "router.currentRoute.path"
|
|
78
|
+
agent-view eval --target sync-worker "self.queue.length" # SharedWorker / ServiceWorker by id or substring
|
|
79
|
+
agent-view eval --await "fetch('/api/health').then(r => r.status)"
|
|
80
|
+
agent-view eval --json "({ buttons: document.querySelectorAll('button').length })"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
When to reach for `eval` instead of `dom`:
|
|
84
|
+
- The truth lives in JS state, not the DOM (Pinia/Vuex/Redux/Zustand store, Vue refs, computed values, app singletons).
|
|
85
|
+
- The target is a worker (`shared_worker`, `service_worker`, `worker`) — DOM doesn't exist there.
|
|
86
|
+
- You need a precise number/string answer, not a tree to scan.
|
|
87
|
+
|
|
88
|
+
### Reactive State (`watch`)
|
|
89
|
+
|
|
90
|
+
Streams JSON-patch diffs of an expression over time. Use when you need to see *what changed* between an action and a final state — `eval` shows the snapshot, `watch` shows the trajectory. **Requires `"allowEval": true`.**
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
agent-view watch "store.cart.total" # 250ms poll, default 10 changes or 30s
|
|
94
|
+
agent-view watch "appState" --until "appState.status === 'ready'" # wait-for-condition with diff log
|
|
95
|
+
agent-view watch "store.user" --max-changes 1 # capture exactly one change after a click
|
|
96
|
+
agent-view watch "appState" --json # NDJSON, machine-readable
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
When to reach for `watch` instead of `eval`:
|
|
100
|
+
- Debugging "the click did X but state shows Y — what happened in between?"
|
|
101
|
+
- Time-based assertions ("wait until store.status === 'ready'") — `--until` exits cleanly when truthy.
|
|
102
|
+
- Confirming an action triggered the *expected* sequence of mutations, not just the final state.
|
|
103
|
+
|
|
104
|
+
Output: `init` line (baseline), one line per RFC 6902 op (`replace /path old → new`, `add /items/0 ...`), final `stop` line with reason. Snapshot size cap 256 KB — narrow the expression (`store.x.y`, not `store`) for large objects.
|
|
105
|
+
|
|
106
|
+
### Console (`console`)
|
|
107
|
+
|
|
108
|
+
Streams `Runtime.consoleAPICalled` + `Log.entryAdded`. Use to confirm a flow finished without errors, or to surface a specific warning after an interaction.
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
agent-view console # buffered messages from auto-attached targets
|
|
112
|
+
agent-view console --level error,warn # filter
|
|
113
|
+
agent-view console --target sync-worker # one target (title/URL substring, same fuzzy semantics as eval --target)
|
|
114
|
+
agent-view console --target IJ56KL # one target (exact id)
|
|
115
|
+
agent-view console --follow --timeout 10 # stream window (use sparingly — 10s of waiting)
|
|
116
|
+
agent-view console --follow --until "ready" # exit as soon as a message contains "ready"
|
|
117
|
+
agent-view console --follow --until "/error/i" # exit on regex match (case-insensitive)
|
|
118
|
+
agent-view console --clear # baseline before an interaction
|
|
119
|
+
agent-view console --since "2026-04-26T10:00:00Z"
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
`--until` requires `--follow`. Exits immediately when a message matches (substring or `/regex/flags`). On timeout without match exits non-zero.
|
|
123
|
+
|
|
124
|
+
Standard pattern for "did this action error?":
|
|
125
|
+
```bash
|
|
126
|
+
agent-view console --clear
|
|
127
|
+
agent-view click --filter "Save"
|
|
128
|
+
agent-view wait --filter "Saved"
|
|
129
|
+
agent-view console --level error # expect "(no console messages)"
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Default attached target types: `page`, `shared_worker`, `service_worker` (override via `consoleTargets` in config).
|
|
133
|
+
|
|
134
|
+
### Targets (`targets`)
|
|
135
|
+
|
|
136
|
+
When `--window` doesn't show what you expected, or you need a worker target id for `eval`/`console`:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
agent-view targets # everything connectable
|
|
140
|
+
agent-view targets --type shared_worker,service_worker # filter
|
|
141
|
+
agent-view targets --json # machine-readable
|
|
47
142
|
```
|
|
48
143
|
|
|
49
|
-
|
|
144
|
+
You usually don't need this — `eval --target <substring>` and `--window <name>` both do fuzzy matching. Reach for `targets` when the substring is ambiguous.
|
|
145
|
+
|
|
146
|
+
### Scene / Canvas / WebGL (only when `webgl` is configured in agent-view.config.json)
|
|
50
147
|
|
|
51
148
|
These commands read the scene graph from canvas-based rendering engines. Skip this section if the project has no `webgl` field in config.
|
|
52
149
|
|
|
@@ -55,9 +152,30 @@ agent-view scene # Scene graph from configured engine
|
|
|
55
152
|
agent-view scene --filter "player" # Filter by object name/type
|
|
56
153
|
agent-view scene --verbose # Extended props (scale, alpha, rotation)
|
|
57
154
|
agent-view scene --diff # Changes since last call
|
|
155
|
+
agent-view scene --compact # Merge single-child chains onto one line (reduces output)
|
|
58
156
|
agent-view snap # DOM + Scene combined
|
|
157
|
+
agent-view snap --scale 0.5 # DOM + Scene + Screenshot (path appended as === Screenshot === section)
|
|
59
158
|
```
|
|
60
159
|
|
|
160
|
+
## Picking the right tool
|
|
161
|
+
|
|
162
|
+
Verifications cost very different amounts. Pick the cheapest tool that can actually answer the question:
|
|
163
|
+
|
|
164
|
+
| The question is about… | Use | Why |
|
|
165
|
+
|---|---|---|
|
|
166
|
+
| Element existence / text / role | `dom --filter` | Cheapest, structured, no vision tokens |
|
|
167
|
+
| Count of matching elements | `dom --filter X --count` | Single integer, no tree output, no ref mutations |
|
|
168
|
+
| App state, store contents, computed values | `eval "expr"` | DOM doesn't expose JS state; reading the tree to infer it is wasteful and unreliable |
|
|
169
|
+
| State *trajectory* — what changed during/after an action | `watch "expr" --until …` or `--max-changes 1` | `eval` shows the final snapshot only; `watch` shows the diffs in order |
|
|
170
|
+
| Worker logic (SharedWorker / ServiceWorker) | `eval --target <name>` | Workers have no DOM at all |
|
|
171
|
+
| Did the last action throw or warn? | `console --clear` before, `console --level error,warn` after | Catches errors that don't surface in the DOM |
|
|
172
|
+
| Layout/visual of a specific element | `screenshot --crop "<element>"` | ~1.6k tokens (1 tile) — crops to bounding box, massive token win |
|
|
173
|
+
| Layout, spacing, full-window visual regression | `screenshot --scale 0.5` | The only tool that sees pixels — but expensive (~6k tokens), use last |
|
|
174
|
+
| Canvas/WebGL scene contents | `scene --diff` | DOM is empty for canvas apps |
|
|
175
|
+
| What DOM nodes changed after an interaction | `dom --diff` | Returns only `+`/`-` lines; much cheaper than re-reading the full tree |
|
|
176
|
+
|
|
177
|
+
When two tools could answer the same question, prefer the one higher up the table. A common mistake is screenshotting to check "is the count = 5?" when `eval "store.counter"` returns the number directly for ~50 tokens.
|
|
178
|
+
|
|
61
179
|
## Verification Workflow
|
|
62
180
|
|
|
63
181
|
### Ad-hoc Mode (standalone)
|
|
@@ -66,10 +184,12 @@ After making code changes:
|
|
|
66
184
|
|
|
67
185
|
1. **Determine affected areas** from git diff
|
|
68
186
|
2. **Ensure app is running**: `agent-view launch` or `agent-view discover`
|
|
69
|
-
3. **Inspect DOM**: `agent-view dom --filter "<area>"` — check structure matches expectations
|
|
70
|
-
4. **
|
|
71
|
-
5. **
|
|
72
|
-
6. **For
|
|
187
|
+
3. **Inspect DOM**: `agent-view dom --filter "<area>" --depth 2` — check structure matches expectations
|
|
188
|
+
4. **Interact if needed**: `agent-view click`/`fill` → `agent-view dom --filter` to verify state changed
|
|
189
|
+
5. **For canvas apps**: `agent-view scene --diff` to see what changed
|
|
190
|
+
6. **For non-DOM truth** (store, computed values, worker state): `agent-view eval` — much cheaper than reading the DOM tree to infer state
|
|
191
|
+
7. **After any interaction that could fail silently**: `agent-view console --level error` — catches uncaught exceptions, network failures, framework warnings
|
|
192
|
+
8. **Screenshot only for final visual confirm**: `agent-view screenshot --scale 0.5` — captures layout/styling that DOM can't reveal
|
|
73
193
|
|
|
74
194
|
### Scenario Execution Mode (from plan)
|
|
75
195
|
|
|
@@ -78,7 +198,7 @@ When UI scenarios are pre-generated (e.g., from a plan file with `## UI Scenario
|
|
|
78
198
|
1. **Read scenario steps** with symbolic refs (`$var` notation)
|
|
79
199
|
2. **Resolve each $var**: `agent-view dom --filter "<text>" --depth 3` → map to ref ID
|
|
80
200
|
3. **Execute steps** sequentially: fill, click, dom --filter (verify expected outcome)
|
|
81
|
-
4. **Screenshot**:
|
|
201
|
+
4. **Screenshot**: `agent-view screenshot --scale 0.5` — only on FAIL and at E2E scenario end, not every step
|
|
82
202
|
5. **Report per-scenario**: PASS / FAIL with reason and evidence
|
|
83
203
|
|
|
84
204
|
This mode works with any workflow that generates plan files with UI scenarios.
|
|
@@ -97,4 +217,19 @@ This mode works with any workflow that generates plan files with UI scenarios.
|
|
|
97
217
|
- **Multiwindow**: all commands support `--window` flag
|
|
98
218
|
- **Output format**: plain text (DOM, scene), JSON (discover only), file path (screenshot)
|
|
99
219
|
- **Lazy server**: auto-starts on first call, shuts down after 5min idle
|
|
100
|
-
|
|
220
|
+
|
|
221
|
+
## Token Optimization
|
|
222
|
+
|
|
223
|
+
Vision tokens dominate cost. One full-res screenshot ≈ 19k tokens (1920×1080, 12 tiles).
|
|
224
|
+
|
|
225
|
+
| Technique | Savings |
|
|
226
|
+
|---|---|
|
|
227
|
+
| `agent-view eval "expr"` for state checks | Returns one value (~50 tokens) instead of a DOM/screenshot |
|
|
228
|
+
| `agent-view dom --filter "row" --count` | Single integer answer — zero tree tokens |
|
|
229
|
+
| `agent-view dom --filter X --depth 2` | Narrow tree to relevant subtree, cap depth |
|
|
230
|
+
| `agent-view screenshot --scale 0.5` | ~3× fewer vision tokens (4 tiles) |
|
|
231
|
+
| `agent-view screenshot --scale 0.25` | ~12× fewer vision tokens (1 tile, ~1.6k tokens) |
|
|
232
|
+
| `agent-view screenshot --crop "<element>"` | ~12× fewer in best case (1 tile) — crops to element bounding box |
|
|
233
|
+
| DOM/eval-first: screenshot only for final visual confirm | Eliminates most screenshot calls |
|
|
234
|
+
|
|
235
|
+
**Default rule**: if the answer is a value → `eval`; if the answer is "is element X visible/correct?" → `agent-view dom --filter`; if you need pixels for a specific section → `screenshot --crop "<element>"` (one tile); only call `screenshot --scale 0.5` for full-window visual proof.
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: verify-recipe
|
|
3
|
+
description: "Generates a concrete, command-by-command agent-view recipe for verifying a feature or bugfix. Use when the developer wants to write a verify-recipe.md, create a verification plan, build an agent-view recipe, or produce a verify checklist for a change they shipped. Triggers on: write a verify-recipe, write verification steps, generate verify steps for the feature/bug I just shipped/fixed, make a verify-recipe.md, what should I run to verify X, create a verification plan, agent-view recipe for this fix, verify checklist for this feature. Does NOT execute the checks — it authors the plan. For running checks against a live app, use the verify skill instead."
|
|
4
|
+
allowed-tools: Read, Write, Bash(agent-view *)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Verification Recipe Generator
|
|
8
|
+
|
|
9
|
+
You help the developer author a disciplined, cheapest-first verification recipe for a feature they shipped or a bug they fixed. You do not run the checks — you produce a `.claude/verify-recipes/<slug>.md` file that any AI coding agent can execute later.
|
|
10
|
+
|
|
11
|
+
## What this produces
|
|
12
|
+
|
|
13
|
+
A file at `.claude/verify-recipes/<kebab-slug>.md` containing:
|
|
14
|
+
|
|
15
|
+
- **REPRO STEPS** — exact state the app must be in before checks run
|
|
16
|
+
- **NARROWED SIGNAL** — the measurable indicator that proves success or failure
|
|
17
|
+
- **EVIDENCE COMMANDS** — ordered `agent-view` calls, cheapest first, each annotated with what it proves
|
|
18
|
+
- **POSITIVE-CASE ASSERTIONS** — what "pass" looks like for each command
|
|
19
|
+
- **REGRESSION CHECKS** — adjacent paths that must not have broken
|
|
20
|
+
|
|
21
|
+
Create the directory if missing: `mkdir -p .claude/verify-recipes`
|
|
22
|
+
|
|
23
|
+
## Methodology
|
|
24
|
+
|
|
25
|
+
Frame the recipe with **hard-debug** discipline. That skill defines the chain: REPRO → narrowed signal → minimize scope → root-cause check → fix verification. Apply the same logic here in authoring mode:
|
|
26
|
+
|
|
27
|
+
1. Start from a reproducible starting state, not "open the app and poke around"
|
|
28
|
+
2. Convert vague expectations ("looks right") into measurable signals ("store.user.role === 'admin'")
|
|
29
|
+
3. Prefer the cheapest tool that can answer the question — a value check costs ~50 tokens, a screenshot costs ~6 000
|
|
30
|
+
4. Include at least one negative-case check (the old symptom must no longer appear)
|
|
31
|
+
5. Include at least one regression check (an adjacent flow must still work)
|
|
32
|
+
|
|
33
|
+
## Tool-cost decision tree
|
|
34
|
+
|
|
35
|
+
Pick the first row that can answer the question. Only go lower when the row above can't:
|
|
36
|
+
|
|
37
|
+
| Question | Command | Why it's cheapest |
|
|
38
|
+
|---|---|---|
|
|
39
|
+
| Element exists / has specific text / role | `agent-view dom --filter "<text>" --depth 2` | Structured text, zero vision tokens |
|
|
40
|
+
| App state, store value, computed flag | `agent-view eval "<expr>"` | Returns the value directly; DOM inference is wasteful and fragile |
|
|
41
|
+
| What changed between action and final state | `agent-view watch "<expr>" --until "<condition>"` or `--max-changes 1` | `eval` shows the snapshot; `watch` shows the trajectory |
|
|
42
|
+
| SharedWorker / ServiceWorker internal state | `agent-view eval --target <name> "<expr>"` | Workers have no DOM; this is the only path |
|
|
43
|
+
| Did this action throw or warn silently? | `agent-view console --clear` before, `agent-view console --level error,warn` after | Catches uncaught exceptions and network failures invisible to DOM |
|
|
44
|
+
| Layout, spacing, visual regression | `agent-view screenshot --scale 0.5` | Last resort — the only tool that sees pixels, but costs ~6 000 tokens |
|
|
45
|
+
| Canvas / WebGL scene state | `agent-view scene --diff` | DOM is empty for canvas apps |
|
|
46
|
+
|
|
47
|
+
**Anti-patterns to reject:**
|
|
48
|
+
- Opening with a screenshot to "see the state" — use `dom --filter` or `eval` first
|
|
49
|
+
- Using `eval` when `dom --filter` answers the question
|
|
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
|
|
52
|
+
|
|
53
|
+
## Workflow
|
|
54
|
+
|
|
55
|
+
### Step 1 — gather context
|
|
56
|
+
|
|
57
|
+
When invoked, ask the developer in plain text (no tool calls yet):
|
|
58
|
+
|
|
59
|
+
1. What was shipped or fixed? (feature name or bug description)
|
|
60
|
+
2. What was the original symptom or expected behavior?
|
|
61
|
+
3. Any known failure mode or edge case to cover?
|
|
62
|
+
|
|
63
|
+
Wait for the response before continuing.
|
|
64
|
+
|
|
65
|
+
### Step 2 — draft the recipe
|
|
66
|
+
|
|
67
|
+
Use the answers to produce a recipe with these sections:
|
|
68
|
+
|
|
69
|
+
```markdown
|
|
70
|
+
# Verify: <feature or fix name>
|
|
71
|
+
|
|
72
|
+
Generated: <date>
|
|
73
|
+
Scope: <one sentence describing what this covers>
|
|
74
|
+
|
|
75
|
+
## Repro Steps
|
|
76
|
+
1. <Exact starting state — window open, user logged in, specific route, etc.>
|
|
77
|
+
2. <Action(s) that trigger the behavior under test>
|
|
78
|
+
|
|
79
|
+
## Narrowed Signal
|
|
80
|
+
<!-- The one measurable thing that proves it works -->
|
|
81
|
+
`<agent-view command>` must return `<expected value>`.
|
|
82
|
+
|
|
83
|
+
## Evidence Commands
|
|
84
|
+
|
|
85
|
+
### 1. <What this proves>
|
|
86
|
+
```bash
|
|
87
|
+
agent-view <command>
|
|
88
|
+
```
|
|
89
|
+
Expected: <concrete criterion — value, text, absence of error>
|
|
90
|
+
Cost: ~<N> tokens
|
|
91
|
+
|
|
92
|
+
### 2. ...
|
|
93
|
+
|
|
94
|
+
## Positive-Case Assertions
|
|
95
|
+
- [ ] <criterion>
|
|
96
|
+
- [ ] <criterion>
|
|
97
|
+
|
|
98
|
+
## Regression Checks
|
|
99
|
+
- [ ] <adjacent flow> — `agent-view <command>` → `<expected>`
|
|
100
|
+
|
|
101
|
+
## Anti-patterns avoided
|
|
102
|
+
- <note any recipe-specific traps, e.g. "state resets on reload — watch needed before dom check">
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Step 3 — save the file
|
|
106
|
+
|
|
107
|
+
Determine a kebab-slug from the feature/fix name (e.g. `login-redirect-fix`, `cart-total-display`).
|
|
108
|
+
|
|
109
|
+
Save to `.claude/verify-recipes/<slug>.md`. Create the directory first if it doesn't exist.
|
|
110
|
+
|
|
111
|
+
Confirm the path to the developer.
|
|
112
|
+
|
|
113
|
+
## Worked example: "fixed login redirect bug"
|
|
114
|
+
|
|
115
|
+
**Developer input:**
|
|
116
|
+
> Fixed a bug where after login, the redirect went to `/home` instead of `/dashboard`. Store mutation `SET_REDIRECT_PATH` was missing. No visual change — purely a routing issue.
|
|
117
|
+
|
|
118
|
+
**Recipe produced:**
|
|
119
|
+
|
|
120
|
+
```markdown
|
|
121
|
+
# Verify: Login Redirect Fix
|
|
122
|
+
|
|
123
|
+
Generated: 2026-04-27
|
|
124
|
+
Scope: Confirms that a successful login routes to /dashboard, not /home, and that the store mutation fires correctly.
|
|
125
|
+
|
|
126
|
+
## Repro Steps
|
|
127
|
+
1. App running, user logged out, at `/login`
|
|
128
|
+
2. Fill email + password, click "Sign in"
|
|
129
|
+
|
|
130
|
+
## Narrowed Signal
|
|
131
|
+
`agent-view eval "router.currentRoute.path"` must return `"/dashboard"`.
|
|
132
|
+
|
|
133
|
+
## Evidence Commands
|
|
134
|
+
|
|
135
|
+
### 0. Setup — baseline console (before any action)
|
|
136
|
+
```bash
|
|
137
|
+
agent-view console --clear
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### 1. Confirm redirect target
|
|
141
|
+
```bash
|
|
142
|
+
agent-view fill <email-ref> "admin@example.com"
|
|
143
|
+
agent-view fill <password-ref> "password"
|
|
144
|
+
agent-view click <signin-ref>
|
|
145
|
+
agent-view watch "router.currentRoute.path" --until "router.currentRoute.path === '/dashboard'"
|
|
146
|
+
```
|
|
147
|
+
Expected: `replace / "/login" → "/dashboard"` in watch output
|
|
148
|
+
Cost: ~100 tokens
|
|
149
|
+
|
|
150
|
+
### 2. Confirm mutation fired
|
|
151
|
+
```bash
|
|
152
|
+
agent-view eval "store.state.auth.redirectPath"
|
|
153
|
+
```
|
|
154
|
+
Expected: `"/dashboard"` (not `"/home"`, not `null`)
|
|
155
|
+
Cost: ~50 tokens
|
|
156
|
+
|
|
157
|
+
### 3. No errors during login flow
|
|
158
|
+
```bash
|
|
159
|
+
agent-view console --level error,warn
|
|
160
|
+
```
|
|
161
|
+
Expected: `(no console messages)`
|
|
162
|
+
Cost: ~30 tokens
|
|
163
|
+
|
|
164
|
+
### 4. Regression — logout returns to /login
|
|
165
|
+
```bash
|
|
166
|
+
agent-view click <logout-ref>
|
|
167
|
+
agent-view eval "router.currentRoute.path"
|
|
168
|
+
```
|
|
169
|
+
Expected: `"/login"`
|
|
170
|
+
Cost: ~60 tokens
|
|
171
|
+
|
|
172
|
+
## Positive-Case Assertions
|
|
173
|
+
- [ ] `router.currentRoute.path` === `/dashboard` after login
|
|
174
|
+
- [ ] `store.state.auth.redirectPath` === `/dashboard`
|
|
175
|
+
- [ ] No console errors during the flow
|
|
176
|
+
|
|
177
|
+
## Regression Checks
|
|
178
|
+
- [ ] Logout → `/login` still works
|
|
179
|
+
|
|
180
|
+
## Anti-patterns avoided
|
|
181
|
+
- Not using screenshot to confirm route (route is a string — eval is 120× cheaper)
|
|
182
|
+
- watch used before eval so route change is confirmed to have settled, not just sampled mid-transition
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**Saved to:** `.claude/verify-recipes/login-redirect-fix.md`
|