@petukhovart/agent-view 0.15.0 → 0.17.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 +1 -1
- package/README.md +34 -11
- package/dist/cdp/png.d.ts +15 -0
- package/dist/cdp/png.d.ts.map +1 -0
- package/dist/cdp/png.js +147 -0
- package/dist/cdp/png.js.map +1 -0
- package/dist/cdp/transport.d.ts +2 -0
- package/dist/cdp/transport.d.ts.map +1 -1
- package/dist/cdp/transport.js +233 -50
- package/dist/cdp/transport.js.map +1 -1
- package/dist/cdp/types.d.ts +72 -6
- package/dist/cdp/types.d.ts.map +1 -1
- package/dist/cdp/types.js.map +1 -1
- package/dist/cli/client.d.ts.map +1 -1
- package/dist/cli/client.js +1 -3
- package/dist/cli/client.js.map +1 -1
- package/dist/cli/commands/act.d.ts +3 -0
- package/dist/cli/commands/act.d.ts.map +1 -0
- package/dist/cli/commands/act.js +19 -0
- package/dist/cli/commands/act.js.map +1 -0
- package/dist/cli/commands/click.d.ts +2 -0
- package/dist/cli/commands/click.d.ts.map +1 -1
- package/dist/cli/commands/click.js +9 -4
- package/dist/cli/commands/click.js.map +1 -1
- package/dist/cli/commands/dom.d.ts.map +1 -1
- package/dist/cli/commands/dom.js +1 -0
- package/dist/cli/commands/dom.js.map +1 -1
- package/dist/cli/commands/drag.d.ts +4 -0
- package/dist/cli/commands/drag.d.ts.map +1 -1
- package/dist/cli/commands/drag.js +18 -0
- package/dist/cli/commands/drag.js.map +1 -1
- package/dist/cli/commands/fill.d.ts +2 -0
- package/dist/cli/commands/fill.d.ts.map +1 -1
- package/dist/cli/commands/fill.js +11 -4
- package/dist/cli/commands/fill.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 +10 -1
- package/dist/cli/commands/screenshot.js.map +1 -1
- package/dist/cli/commands/wait.d.ts +3 -1
- package/dist/cli/commands/wait.d.ts.map +1 -1
- package/dist/cli/commands/wait.js +6 -2
- package/dist/cli/commands/wait.js.map +1 -1
- package/dist/cli/commands/watch.js +1 -1
- package/dist/cli/commands/watch.js.map +1 -1
- package/dist/cli/index.js +51 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/config/manager.d.ts.map +1 -1
- package/dist/config/manager.js +4 -0
- package/dist/config/manager.js.map +1 -1
- package/dist/config/types.d.ts +5 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/inspectors/controls/index.d.ts +39 -0
- package/dist/inspectors/controls/index.d.ts.map +1 -0
- package/dist/inspectors/controls/index.js +140 -0
- package/dist/inspectors/controls/index.js.map +1 -0
- package/dist/inspectors/dom/index.d.ts +2 -0
- package/dist/inspectors/dom/index.d.ts.map +1 -1
- package/dist/inspectors/dom/index.js +21 -14
- package/dist/inspectors/dom/index.js.map +1 -1
- package/dist/server/act-replay.d.ts +23 -0
- package/dist/server/act-replay.d.ts.map +1 -0
- package/dist/server/act-replay.js +143 -0
- package/dist/server/act-replay.js.map +1 -0
- package/dist/server/act-script.d.ts +46 -0
- package/dist/server/act-script.d.ts.map +1 -0
- package/dist/server/act-script.js +46 -0
- package/dist/server/act-script.js.map +1 -0
- package/dist/server/act-session.d.ts +23 -0
- package/dist/server/act-session.d.ts.map +1 -0
- package/dist/server/act-session.js +304 -0
- package/dist/server/act-session.js.map +1 -0
- package/dist/server/locator.d.ts +19 -0
- package/dist/server/locator.d.ts.map +1 -0
- package/dist/server/locator.js +33 -0
- package/dist/server/locator.js.map +1 -0
- package/dist/server/port.d.ts +7 -0
- package/dist/server/port.d.ts.map +1 -0
- package/dist/server/port.js +19 -0
- package/dist/server/port.js.map +1 -0
- package/dist/server/server.d.ts +1 -0
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +89 -25
- package/dist/server/server.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/skills/verify/SKILL.md +12 -20
- package/skills/verify/references/commands.md +127 -6
|
@@ -11,6 +11,7 @@ listing call — always expand from the most recent one.
|
|
|
11
11
|
- [Interaction](#interaction) — `click`, `fill`, `drag`
|
|
12
12
|
- [Modals & file pickers](#modals--file-pickers-dialog-upload) — `dialog`, `upload`
|
|
13
13
|
- [Waiting](#waiting-wait) — `wait`
|
|
14
|
+
- [Step protocol](#step-protocol-act) — `act`
|
|
14
15
|
- [Screenshots](#screenshots) — `screenshot`
|
|
15
16
|
- [Runtime state](#runtime-state-eval) — `eval`
|
|
16
17
|
- [Reactive state](#reactive-state-watch) — `watch`
|
|
@@ -48,6 +49,15 @@ agent-view dom --diff # Lines changed since last dom call (+ a
|
|
|
48
49
|
|
|
49
50
|
`--count` skips tree output and ref mutations — cheapest way to assert "element exists N times" without loading the full tree into context.
|
|
50
51
|
|
|
52
|
+
**Test ids.** A node carrying a test id prints it: `button "Save" [testid=save-btn] [ref=12]`. An
|
|
53
|
+
unnamed wrapper that carries one is printed too (`generic [testid=email] [ref=6]`), because
|
|
54
|
+
component libraries put the id on the wrapper. The attribute is `testIdAttribute` from
|
|
55
|
+
`agent-view.config.json`; without it `data-testid`, `data-test-id`, `data-test`, `data-qa` and
|
|
56
|
+
`data-cy` are all read. A test id survives HMR, navigation and text changes; a ref does not. Once
|
|
57
|
+
`dom` has shown a test id, address the element with `--testid` (below). Limit: an element absent
|
|
58
|
+
from the AX tree prints no line. An inline `<span data-testid>` holding only text prints as its
|
|
59
|
+
`StaticText`, without the id. `--testid` still finds it.
|
|
60
|
+
|
|
51
61
|
### Interaction
|
|
52
62
|
```bash
|
|
53
63
|
agent-view click <ref> # Click element by ref from dom output
|
|
@@ -55,21 +65,40 @@ agent-view click --filter "Save" # Find element by text and click
|
|
|
55
65
|
agent-view click --pos 100,200 # Click by coordinates — CANVAS ONLY, see below
|
|
56
66
|
agent-view click <ref> --double # Double-click (fires dblclick handlers); works with --filter / --pos too
|
|
57
67
|
agent-view click <ref> --right # Right-click (fires contextmenu); works with --filter / --pos too
|
|
68
|
+
agent-view click --testid save-btn # By test id (see "Test ids" above)
|
|
69
|
+
agent-view click --selector "tr:nth-child(3) button" # By CSS selector
|
|
58
70
|
agent-view fill <ref> "text" # Type into input field
|
|
71
|
+
agent-view fill --testid email "a@b.c" # A test id on a wrapper resolves to the input/textarea inside
|
|
59
72
|
agent-view drag --from <ref> --to <ref> # Drag element to another element by ref
|
|
60
73
|
agent-view drag --from-pos 50,80 --to-pos 200,300 # Drag by coordinates (for canvas / Pixi)
|
|
61
74
|
agent-view drag --from <ref> --to <ref> --steps 25 --hold-ms 60 # Smoother movement, longer hold
|
|
75
|
+
agent-view drag --from-pos 385,303 --to-pos 1250,589 --cancel # HTML5: dragCancel instead of drop
|
|
76
|
+
agent-view drag --from-pos 385,303 --to-pos 1250,589 --html5 # Fail unless an HTML5 drag started
|
|
62
77
|
```
|
|
63
78
|
|
|
64
|
-
`drag`
|
|
79
|
+
`drag` presses and moves via CDP; if Chromium starts an HTML5 drag (`draggable=true`) it takes it
|
|
80
|
+
over with `Input.dispatchDragEvent` and drops with the app's real `dataTransfer`, otherwise it is a
|
|
81
|
+
plain pointer drag. The first output line says which: `via html5 drop` followed by one line per
|
|
82
|
+
MIME type (`application/json: "..."`) — check the payload is the app's, not a text selection — or
|
|
83
|
+
`via pointer` with a warning when no HTML5 drag started. Start HTML5 drags on a cell without a
|
|
84
|
+
control: an input/select/button under the cursor swallows `dragstart`. Endpoints can mix
|
|
65
85
|
ref and coordinate (e.g. `--from <ref> --to-pos 400,300`). For canvas/Pixi targets always use
|
|
66
86
|
`--from-pos`/`--to-pos` — derive the centroid via `agent-view eval` from the scene graph.
|
|
67
87
|
Refs are resolved fresh on each call, so window resizes between snapshots are tolerated.
|
|
68
88
|
Increase `--steps` for handlers using `globalpointermove` so intermediate frames are not skipped.
|
|
69
89
|
|
|
90
|
+
`--testid` / `--selector` act on the **first visible** match; hidden copies (`v-show`, a closed
|
|
91
|
+
popover) are skipped. When several match, the output says so — `Clicked testid "row" (first visible
|
|
92
|
+
of 3)` — and the address is too broad: narrow it, e.g. a `--selector` with `:nth-child`. Exit 1 with
|
|
93
|
+
`No element matches testid "x"` when nothing matches, and with `None of 2 element(s) matching
|
|
94
|
+
testid "x" is visible` when every match is hidden. Pass exactly one of `<ref>`, `--filter`,
|
|
95
|
+
`--testid`, `--selector`, `--pos`. `fill` exits 1 with `No input or textarea at or inside the
|
|
96
|
+
element` when the element holds no field.
|
|
97
|
+
|
|
70
98
|
**Coordinates are a last resort.** `--pos` / `--from-pos` / `--to-pos` exist for canvas and WebGL,
|
|
71
|
-
where no ref exists. On DOM
|
|
72
|
-
`click <ref>`, or `click --filter "<text>"` in one
|
|
99
|
+
where no ref exists. On DOM, use `--testid` when `dom` shows one. Otherwise run
|
|
100
|
+
`dom --filter "<text>"` → take the `[ref=N]` → `click <ref>`, or `click --filter "<text>"` in one
|
|
101
|
+
step. A coordinate pair breaks on any layout
|
|
73
102
|
shift, scroll, zoom, or window resize, and it clicks whatever now sits at that point — silently.
|
|
74
103
|
If you reach for `--pos` on a DOM element, first say why the ref was not usable.
|
|
75
104
|
|
|
@@ -141,25 +170,117 @@ an IPC channel) are out of reach — CDP does not see the main process.
|
|
|
141
170
|
agent-view wait --filter "Saved" # until the text appears in the AX tree
|
|
142
171
|
agent-view wait --filter "Saved" --timeout 20 # max wait in seconds (default 10)
|
|
143
172
|
agent-view wait --filter "Row 5" --window "Main" # specific window
|
|
173
|
+
agent-view wait --testid order-saved # until an element with this test id is visible
|
|
174
|
+
agent-view wait --selector ".toast.success" # until a selector match is visible
|
|
144
175
|
```
|
|
145
176
|
|
|
146
|
-
Exits as soon as the element appears; exits
|
|
177
|
+
Exactly one of `--filter`, `--testid`, `--selector`. Exits as soon as the element appears; exits
|
|
178
|
+
non-zero on timeout — so `&&` after it is a real gate.
|
|
179
|
+
A mounted but hidden match (`v-show`, `display:none`, `visibility:hidden`) does not end a
|
|
180
|
+
`--testid` / `--selector` wait. On timeout the error says whether nothing matched or every match
|
|
181
|
+
was hidden.
|
|
147
182
|
|
|
148
183
|
**Never sleep for a fixed time** — see the waiting-signal table in `SKILL.md`. If no condition-based
|
|
149
184
|
wait fits, poll `dom --filter X --count` with an explicit attempt cap and report the attempt count.
|
|
150
185
|
|
|
151
186
|
|
|
187
|
+
### Step protocol (`act`)
|
|
188
|
+
|
|
189
|
+
For a driver that only ever answers `op n [text]`. Each call acts, waits for the UI to settle,
|
|
190
|
+
checks the done condition, and prints a fresh numbered control table. The done condition is
|
|
191
|
+
agent-view's to check, never the driver's: `act start` needs exactly one of `--until-testid`,
|
|
192
|
+
`--until-selector`.
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
agent-view act start --until-testid workspace-root # new session for this CDP port; prints the table
|
|
196
|
+
agent-view act start --until-selector ".dashboard" --max-steps 20 # budget, default 30
|
|
197
|
+
agent-view act table # re-snapshot, print the table
|
|
198
|
+
agent-view act click 3 # row numbers refer to the LAST printed table
|
|
199
|
+
agent-view act type 1 "admin" # fill
|
|
200
|
+
agent-view act select 4 "Monthly" # native <select> only
|
|
201
|
+
agent-view act scroll down # wheel ~0.8 viewport at its centre; also `up`
|
|
202
|
+
agent-view act do "type 2 root" "type 3 secret" "click 1" # several ops, all numbered from ONE table; stops at the first BLOCKED/DONE/error
|
|
203
|
+
agent-view act drag 5 # pointer-drag row 5 onto the viewport centre
|
|
204
|
+
agent-view act drag 5 2 # … onto the centre of row 2
|
|
205
|
+
agent-view act drag 7 testid=video-panel right # … onto any visible element by test id, 20 px inside its right edge
|
|
206
|
+
agent-view act drag 7 center left # … near the viewport's left edge; edge: left|right|top|bottom|center (default)
|
|
207
|
+
agent-view act wait # no action: settle up to 3 s, print the table (not a step)
|
|
208
|
+
agent-view act save login # writes ~/.agent-view/scratch/login.json, prints the path
|
|
209
|
+
agent-view act start --until-testid x --save login # same, written automatically on DONE (one turn fewer)
|
|
210
|
+
AGENT_VIEW_SECRET=… agent-view act replay login # re-run it with no model; exit 0 DONE, 1 FAIL, 3 STALE, 2 error
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Table — interactive controls visible in the viewport, renumbered from 1 on every print, capped at
|
|
214
|
+
150 rows (`… N more below — act scroll down`). Named `alert` / `status` nodes (a snackbar) are listed
|
|
215
|
+
too, so the driver sees why a form came back. A field wrapper that boxes a field of its own role
|
|
216
|
+
(Vuetify `v-field` around its input) is folded into the inner one. After the AX rows come `item`
|
|
217
|
+
rows: elements with no interactive role but a test id and computed `cursor: pointer` (a
|
|
218
|
+
`<div @pointerdown>` widget-bar entry), so they can be clicked or dragged; one inside a control is
|
|
219
|
+
that control. Password values print as `••••`, or `empty`:
|
|
220
|
+
|
|
221
|
+
```
|
|
222
|
+
act step 2/30 · 14 controls · until testid "workspace-root"
|
|
223
|
+
[1] textbox "Логин" testid=login-input · "admin"
|
|
224
|
+
[2] textbox "Пароль" testid=password · ••••
|
|
225
|
+
[3] button "Войти" testid=login-btn
|
|
226
|
+
[4] checkbox "Запомнить" · checked
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
First line of an op's output:
|
|
230
|
+
|
|
231
|
+
| Line | Meaning |
|
|
232
|
+
|---|---|
|
|
233
|
+
| `✓ click [3] button "Войти" · 240ms` | acted and settled; the new table follows |
|
|
234
|
+
| `✓ click [3] button "Войти" · window reloaded · 900ms` | the window reloaded under the action (login); settled on the new document |
|
|
235
|
+
| `✓ drag [7] item "ГИС" testid=nav__widgetbar__item-GisWidget → testid=video-panel right · 310ms` | dragged: `→` names the target and edge |
|
|
236
|
+
| `DONE: until testid "workspace-root" · 3 steps · 4.1s` | until condition visible; nothing follows |
|
|
237
|
+
| `BLOCKED: [3] button "Войти" is gone` | row no longer on screen, no unique match; fresh table follows, nothing was done |
|
|
238
|
+
| `BLOCKED: [3] covered by div.overlay testid=spinner` | something else receives the click; fresh table follows, nothing was done |
|
|
239
|
+
| `BLOCKED: step budget 30 exhausted` | `--max-steps` reached |
|
|
240
|
+
|
|
241
|
+
`act wait` runs even after the budget is spent. Errors (non-zero exit):
|
|
242
|
+
|
|
243
|
+
- `` run `agent-view act start` first ``, `act start --until-testid <id> | --until-selector <css> — exactly one`
|
|
244
|
+
- `` this act run is DONE — `agent-view act start` for a new one `` (any step after DONE; `table` / `wait` still work)
|
|
245
|
+
- `No row [n] in the last table (1-N)`
|
|
246
|
+
- `[n] is a <role>, not a text field — pick a textbox/combobox row` (`type` on a non-text row);
|
|
247
|
+
`No input or textarea at or inside the element` (`type` on a native `<select>` — use `select`)
|
|
248
|
+
- `not a native select — click it`, `No option "x" in [n]`
|
|
249
|
+
- `act do: "…" — each step is click|type|select <n> [text]` (checked before any step runs; a
|
|
250
|
+
failing step prints the `✓` lines of the ones before it)
|
|
251
|
+
- `act scroll <up|down>`, `act drag <n> [to] [edge] — edge is one of left|right|top|bottom|center`
|
|
252
|
+
|
|
253
|
+
The saved script names each control by test id, else role + name — never by row number — and
|
|
254
|
+
stores no password. `act replay` runs it inside the server: each step waits (50 ms polls, 10 s cap)
|
|
255
|
+
only for its own control to be on screen, enabled and uncovered, then acts; a window reload
|
|
256
|
+
mid-run is ridden over. Its one line, ending in the total time:
|
|
257
|
+
|
|
258
|
+
| Line | Exit | Meaning |
|
|
259
|
+
|---|---|---|
|
|
260
|
+
| `DONE: replay login · 2 steps in 0.1s, then testid "x" · 1.8s` | 0 | until met; the steps took 0.1 s, the app the rest |
|
|
261
|
+
| `FAIL: replay login — steps ran, testid "x" not visible after 15s · 16.2s` | 1 | the app did not answer — likely a bug |
|
|
262
|
+
| `FAIL: step 2/2 click button "Войти" testid=login-btn — still disabled after 10s · 10.4s` | 1 | the control is there but stayed `disabled` / `covered by …` — likely a bug |
|
|
263
|
+
| `STALE: step 2/2 click button "Войти" — not on screen within 10s · 10.3s` | 3 | the script no longer fits the app — re-record it |
|
|
264
|
+
| `STALE: step 3/3 drag target testid=video-panel not found · 10.5s` | 3 | same, for a drop target |
|
|
265
|
+
| `STALE: step 1/2 select combobox "Период" — no option "Monthly" · 0.2s` | 3 | same, for an option (or `not a native select`) |
|
|
266
|
+
| `STALE: step 2/3 click button "Закрыть" — <CDP error> · 0.4s` | 3 | the control vanished between finding and acting |
|
|
267
|
+
|
|
268
|
+
Exit 2, message on stderr: the replay could not run — `No saved script "x"`, `"x" types a password —
|
|
269
|
+
set AGENT_VIEW_SECRET`, `"x" has no done condition`.
|
|
270
|
+
|
|
152
271
|
### Screenshots
|
|
153
272
|
```bash
|
|
154
|
-
agent-view screenshot --scale 0.5 # Recommended:
|
|
273
|
+
agent-view screenshot --scale 0.5 # Recommended: half-res PNG (~3× fewer vision tokens)
|
|
155
274
|
agent-view screenshot --scale 0.5 --window <id> # Specific window
|
|
156
275
|
agent-view screenshot --crop "Sidebar" # Crop to element bounding box (~1.6k tokens — 12× win)
|
|
157
276
|
agent-view screenshot --crop "Chart" --scale 0.5 # Crop + scale (stacks)
|
|
158
277
|
agent-view screenshot --crop "Active bookings" --crop-up 1 # Crop the card, not just its heading
|
|
278
|
+
agent-view screenshot --testid order-card # Crop to the element with this test id
|
|
279
|
+
agent-view screenshot --selector ".chart" # Crop to the first visible selector match
|
|
159
280
|
agent-view screenshot # Full-res PNG (expensive: ~19k tokens at 1920×1080)
|
|
160
281
|
```
|
|
161
282
|
|
|
162
|
-
`--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.
|
|
283
|
+
`--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. `--testid` / `--selector` crop the same way and take `--crop-up`, but a miss exits 1 instead: an exact address that misses is a wrong address, and a full-window capture would spend ~19k tokens on it. Pass at most one of `--crop`, `--testid`, `--selector`.
|
|
163
284
|
|
|
164
285
|
A text filter usually matches the text-bearing node, so cropping on a section title returns a thin strip of that title. `--crop-up <n>` climbs `n` element ancestors before cropping — use `1` (sometimes `2`) to get the surrounding card/section. When a crop comes back text-sized, the command says so on stderr.
|
|
165
286
|
|