@webhands/core 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.
Files changed (53) hide show
  1. package/README.md +20 -4
  2. package/dist/errors.d.ts +92 -1
  3. package/dist/errors.d.ts.map +1 -1
  4. package/dist/errors.js +100 -0
  5. package/dist/errors.js.map +1 -1
  6. package/dist/hand-host.d.ts +198 -5
  7. package/dist/hand-host.d.ts.map +1 -1
  8. package/dist/hand-host.js +664 -21
  9. package/dist/hand-host.js.map +1 -1
  10. package/dist/index.d.ts +4 -4
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +3 -3
  13. package/dist/index.js.map +1 -1
  14. package/dist/playwright-attach-transport.d.ts +8 -1
  15. package/dist/playwright-attach-transport.d.ts.map +1 -1
  16. package/dist/playwright-attach-transport.js +19 -4
  17. package/dist/playwright-attach-transport.js.map +1 -1
  18. package/dist/playwright-launch-transport.d.ts.map +1 -1
  19. package/dist/playwright-launch-transport.js +13 -4
  20. package/dist/playwright-launch-transport.js.map +1 -1
  21. package/dist/profile-location.d.ts +19 -0
  22. package/dist/profile-location.d.ts.map +1 -1
  23. package/dist/profile-location.js +21 -0
  24. package/dist/profile-location.js.map +1 -1
  25. package/dist/seam.d.ts +501 -7
  26. package/dist/seam.d.ts.map +1 -1
  27. package/dist/seam.js +31 -0
  28. package/dist/seam.js.map +1 -1
  29. package/dist/session-rpc.d.ts +63 -1
  30. package/dist/session-rpc.d.ts.map +1 -1
  31. package/dist/session-rpc.js +174 -11
  32. package/dist/session-rpc.js.map +1 -1
  33. package/dist/stub-transport.d.ts.map +1 -1
  34. package/dist/stub-transport.js +74 -6
  35. package/dist/stub-transport.js.map +1 -1
  36. package/dist/test-fixtures/fixture-pages.d.ts.map +1 -1
  37. package/dist/test-fixtures/fixture-pages.js +994 -0
  38. package/dist/test-fixtures/fixture-pages.js.map +1 -1
  39. package/dist/test-fixtures/fixture-server.d.ts.map +1 -1
  40. package/dist/test-fixtures/fixture-server.js +33 -3
  41. package/dist/test-fixtures/fixture-server.js.map +1 -1
  42. package/package.json +1 -1
  43. package/src/errors.ts +134 -1
  44. package/src/hand-host.ts +797 -21
  45. package/src/index.ts +20 -1
  46. package/src/playwright-attach-transport.ts +25 -3
  47. package/src/playwright-launch-transport.ts +13 -2
  48. package/src/profile-location.ts +25 -0
  49. package/src/seam.ts +535 -7
  50. package/src/session-rpc.ts +276 -14
  51. package/src/stub-transport.ts +83 -6
  52. package/src/test-fixtures/fixture-pages.ts +1010 -0
  53. package/src/test-fixtures/fixture-server.ts +32 -3
package/README.md CHANGED
@@ -83,10 +83,26 @@ This is a **personal-use** tool. Its whole premise is that you drive a browser
83
83
  [`docs/adr/0002`](docs/adr/0002-real-session-over-fingerprint-spoofing.md)). It is
84
84
  deliberately local and single-session by design.
85
85
 
86
- - **No login-bypass, no CAPTCHA-solving.** The human does the one-time login and
87
- clears any anti-bot challenge in the headed `setup-profile` step. This tool
88
- does NOT bypass authentication or solve CAPTCHAs programmatically, and it is not
89
- intended to.
86
+ - **No login-bypass, no built-in CAPTCHA solver.** The human does the one-time
87
+ login and clears any anti-bot challenge in the headed `setup-profile` step.
88
+ webhands ships NO captcha solver and NO provider key, and does not bypass
89
+ authentication itself. What changed: the verb surface is now rich enough that it
90
+ no longer STANDS IN THE WAY of a capable agent that brings its OWN key. Such an
91
+ agent can get past a captcha by poking the page with verbs, both families: the
92
+ token-harvest family by reading the sitekey with a frame-aware `query`, `type`ing
93
+ a provider token into the response sink, and firing the callback; the vision/tile
94
+ family with the coordinate `mouse`, the element-clipped `screenshot`, and the
95
+ cross-origin frame read. We do not solve it; we no longer stand in the way. The
96
+ agent supplies its own key and its own logic (or uses a hand, below). webhands
97
+ is capable, not a solver.
98
+ - **Hands are the simpler path (still).** A *hand* is a third-party capability
99
+ module (`iamhuman` today, a future buy-on-amazon hand) that closes over the live
100
+ page and makes the hard thing ONE call. A dumb agent plus a hand still gets there
101
+ in a single call, even though a capable agent can now do the same over several
102
+ verb turns. The two paths coexist: the verb surface is the floor that makes the
103
+ unaided path POSSIBLE; a hand is the ramp that makes it EASY. (A hand is a
104
+ trusted in-process peer, loaded only when you name it in `hands.json`; see
105
+ [`docs/adr/0007`](docs/adr/0007-public-hand-contract-and-explicit-declarative-loading.md).)
90
106
  - **No fingerprint-spoofing / anti-detect tricks.** It leans on being a *real*
91
107
  browser/profile/IP rather than spoofing. There is no proxy *rotation* or
92
108
  anti-detect build here. (A single, user-chosen SOCKS proxy for traffic/DNS
package/dist/errors.d.ts CHANGED
@@ -15,7 +15,7 @@
15
15
  * has to re-derive paths.
16
16
  */
17
17
  /** The closed set of identifiable `core` error conditions. */
18
- export type ControllerErrorCode = 'missing-browser-binary' | 'missing-stealth-dependency' | 'invalid-proxy' | 'missing-profile' | 'attach-not-chromium' | 'attach-no-context' | 'no-live-server' | 'session-already-active';
18
+ export type ControllerErrorCode = 'missing-browser-binary' | 'missing-stealth-dependency' | 'invalid-proxy' | 'missing-profile' | 'attach-not-chromium' | 'attach-no-context' | 'no-live-server' | 'session-already-active' | 'cross-origin-frame' | 'screenshot-path-outside-managed-dir' | 'stale-ref';
19
19
  /**
20
20
  * Base class for every identifiable `core` error. Branch on {@link code}.
21
21
  *
@@ -159,6 +159,97 @@ export declare class SessionAlreadyActiveError extends ControllerError {
159
159
  cause?: unknown;
160
160
  });
161
161
  }
162
+ /**
163
+ * A frame-scoped `eval` (or any same-origin-frame op) addressed a CROSS-ORIGIN
164
+ * child frame. Page-world JS cannot cross a browser security boundary, so the
165
+ * frame-scoped `eval` reaches the top document and SAME-ORIGIN descendant frames
166
+ * ONLY (the idea's honest-scope note); a cross-origin frame is unreachable BY
167
+ * DESIGN, not a missing feature. We refuse LOUDLY with this typed condition
168
+ * rather than return a silent empty result, because a silent empty would let an
169
+ * agent believe its callback fired / its read succeeded when the security
170
+ * boundary actually blocked it.
171
+ *
172
+ * Cross-origin frame reach is the SEPARATE Tier-4 `frameLocator`/coordinate
173
+ * surface, not this verb; the message points there so the agent is not left
174
+ * guessing. Mirrors the other typed conditions: the CLI maps {@link code} to a
175
+ * message, and {@link isControllerError} narrows it across a bundle boundary.
176
+ */
177
+ export declare class CrossOriginFrameError extends ControllerError {
178
+ readonly code = "cross-origin-frame";
179
+ /** The frame selector the caller passed (echoed back so it is visible). */
180
+ readonly frame: string;
181
+ /** The cross-origin frame's origin, when known (e.g. `https://hcaptcha.com`). */
182
+ readonly frameOrigin?: string;
183
+ /** The page's own (main-frame) origin the frame had to match. */
184
+ readonly pageOrigin?: string;
185
+ constructor(frame: string, details?: {
186
+ frameOrigin?: string;
187
+ pageOrigin?: string;
188
+ }, message?: string, options?: {
189
+ cause?: unknown;
190
+ });
191
+ }
192
+ /**
193
+ * A `screenshot --out <path>` override pointed OUTSIDE the managed screenshots
194
+ * dir. webhands MINTS screenshots under one managed directory it owns (under the
195
+ * controller home root, beside `profiles/`); a caller MAY override the output
196
+ * path, but only WITHIN that managed dir (prd `broaden-agent-verb-surface`, R3:
197
+ * "validate it stays under a sane managed dir"). An override that escapes it
198
+ * (an absolute path elsewhere, or a `..` traversal out) is refused LOUDLY with
199
+ * this typed condition rather than silently writing a PNG to an arbitrary
200
+ * filesystem location — the seam returns a path, so an unbounded path would let
201
+ * the verb clobber any file the process can write.
202
+ *
203
+ * Mirrors the other typed conditions: the CLI maps {@link code} to a message,
204
+ * and {@link isControllerError} narrows it across a bundle boundary.
205
+ */
206
+ export declare class ScreenshotPathError extends ControllerError {
207
+ readonly code = "screenshot-path-outside-managed-dir";
208
+ /** The offending caller-supplied `out` path, echoed back so it is visible. */
209
+ readonly path: string;
210
+ /** The managed screenshots dir the path had to stay under. */
211
+ readonly managedDir: string;
212
+ constructor(path: string, managedDir: string, message?: string, options?: {
213
+ cause?: unknown;
214
+ });
215
+ }
216
+ /**
217
+ * A durable `query` `ref` (prd `broaden-agent-verb-surface`, R4; finding
218
+ * `query-ref-mint-mechanism-attribute-beats-weakmap`) failed to resolve to
219
+ * EXACTLY ONE element when an action verb (`click`/`type`) tried to act on it.
220
+ * A `ref` is a SHORT-LIVED handle, not a stable identity: between the `query`
221
+ * that minted it and the act, the page may have re-rendered (React keyed-list /
222
+ * Svelte `{#each}` NODE REPLACEMENT), navigated, or cloned a subtree carrying
223
+ * our minted attribute. Two stale shapes, BOTH this one error, never a silent
224
+ * wrong-element action:
225
+ *
226
+ * - resolve-to-ZERO ({@link matched} `=== 0`) — the element was removed or
227
+ * replaced (its minted node is gone, or a reused stable attribute it carried
228
+ * no longer exists). The agent must re-`query` against the fresh DOM.
229
+ * - resolve-to-MANY ({@link matched} `> 1`) — the ref matches more than one
230
+ * element (a framework cloned a subtree carrying our minted attribute, or a
231
+ * reused attribute turned out non-unique after a mutation). We refuse to
232
+ * "pick the first", because that is exactly the silent wrong-element click the
233
+ * ref exists to PREVENT.
234
+ *
235
+ * This is STRICTLY SAFER than re-addressing by a positional `.nth(i)`, which
236
+ * SILENTLY clicks whatever now sits at that index. The agent is told "re-query,
237
+ * the page changed" — its natural loop anyway. Mirrors the other typed
238
+ * conditions: the CLI maps {@link code} to a message, and
239
+ * {@link isControllerError} narrows it across a bundle boundary.
240
+ */
241
+ export declare class StaleRefError extends ControllerError {
242
+ readonly code = "stale-ref";
243
+ /** The ref locator string that went stale (echoed back so it is visible). */
244
+ readonly ref: string;
245
+ /** How many elements the ref resolved to (0 = removed/replaced, >1 = ambiguous). */
246
+ readonly matched: number;
247
+ /** Which verb tried to act on the stale ref (e.g. `click`, `type`). */
248
+ readonly verb: string;
249
+ constructor(ref: string, matched: number, verb: string, message?: string, options?: {
250
+ cause?: unknown;
251
+ });
252
+ }
162
253
  /**
163
254
  * Narrow an unknown caught value to a {@link ControllerError}. Prefer this over
164
255
  * `instanceof` at package boundaries: it checks the {@link ControllerError.isControllerError}
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
package/dist/errors.js CHANGED
@@ -165,6 +165,106 @@ export class SessionAlreadyActiveError extends ControllerError {
165
165
  super(message, options);
166
166
  }
167
167
  }
168
+ /**
169
+ * A frame-scoped `eval` (or any same-origin-frame op) addressed a CROSS-ORIGIN
170
+ * child frame. Page-world JS cannot cross a browser security boundary, so the
171
+ * frame-scoped `eval` reaches the top document and SAME-ORIGIN descendant frames
172
+ * ONLY (the idea's honest-scope note); a cross-origin frame is unreachable BY
173
+ * DESIGN, not a missing feature. We refuse LOUDLY with this typed condition
174
+ * rather than return a silent empty result, because a silent empty would let an
175
+ * agent believe its callback fired / its read succeeded when the security
176
+ * boundary actually blocked it.
177
+ *
178
+ * Cross-origin frame reach is the SEPARATE Tier-4 `frameLocator`/coordinate
179
+ * surface, not this verb; the message points there so the agent is not left
180
+ * guessing. Mirrors the other typed conditions: the CLI maps {@link code} to a
181
+ * message, and {@link isControllerError} narrows it across a bundle boundary.
182
+ */
183
+ export class CrossOriginFrameError extends ControllerError {
184
+ code = 'cross-origin-frame';
185
+ /** The frame selector the caller passed (echoed back so it is visible). */
186
+ frame;
187
+ /** The cross-origin frame's origin, when known (e.g. `https://hcaptcha.com`). */
188
+ frameOrigin;
189
+ /** The page's own (main-frame) origin the frame had to match. */
190
+ pageOrigin;
191
+ constructor(frame, details, message = `The frame ${JSON.stringify(frame)} is CROSS-ORIGIN${details?.frameOrigin !== undefined && details?.pageOrigin !== undefined
192
+ ? ` (frame origin ${details.frameOrigin}, page origin ${details.pageOrigin})`
193
+ : ''} and is unreachable from page-world JS. eval --frame reaches the top document and SAME-ORIGIN child frames only; a cross-origin frame is a browser security boundary. Reach cross-origin frames with the Tier-4 frameLocator/coordinate ops instead.`, options) {
194
+ super(message, options);
195
+ this.frame = frame;
196
+ this.frameOrigin = details?.frameOrigin;
197
+ this.pageOrigin = details?.pageOrigin;
198
+ }
199
+ }
200
+ /**
201
+ * A `screenshot --out <path>` override pointed OUTSIDE the managed screenshots
202
+ * dir. webhands MINTS screenshots under one managed directory it owns (under the
203
+ * controller home root, beside `profiles/`); a caller MAY override the output
204
+ * path, but only WITHIN that managed dir (prd `broaden-agent-verb-surface`, R3:
205
+ * "validate it stays under a sane managed dir"). An override that escapes it
206
+ * (an absolute path elsewhere, or a `..` traversal out) is refused LOUDLY with
207
+ * this typed condition rather than silently writing a PNG to an arbitrary
208
+ * filesystem location — the seam returns a path, so an unbounded path would let
209
+ * the verb clobber any file the process can write.
210
+ *
211
+ * Mirrors the other typed conditions: the CLI maps {@link code} to a message,
212
+ * and {@link isControllerError} narrows it across a bundle boundary.
213
+ */
214
+ export class ScreenshotPathError extends ControllerError {
215
+ code = 'screenshot-path-outside-managed-dir';
216
+ /** The offending caller-supplied `out` path, echoed back so it is visible. */
217
+ path;
218
+ /** The managed screenshots dir the path had to stay under. */
219
+ managedDir;
220
+ constructor(path, managedDir, message = `The screenshot output path ${JSON.stringify(path)} is OUTSIDE the managed screenshots dir (${managedDir}). A caller may override --out only within the managed dir; webhands never writes a screenshot to an arbitrary location.`, options) {
221
+ super(message, options);
222
+ this.path = path;
223
+ this.managedDir = managedDir;
224
+ }
225
+ }
226
+ /**
227
+ * A durable `query` `ref` (prd `broaden-agent-verb-surface`, R4; finding
228
+ * `query-ref-mint-mechanism-attribute-beats-weakmap`) failed to resolve to
229
+ * EXACTLY ONE element when an action verb (`click`/`type`) tried to act on it.
230
+ * A `ref` is a SHORT-LIVED handle, not a stable identity: between the `query`
231
+ * that minted it and the act, the page may have re-rendered (React keyed-list /
232
+ * Svelte `{#each}` NODE REPLACEMENT), navigated, or cloned a subtree carrying
233
+ * our minted attribute. Two stale shapes, BOTH this one error, never a silent
234
+ * wrong-element action:
235
+ *
236
+ * - resolve-to-ZERO ({@link matched} `=== 0`) — the element was removed or
237
+ * replaced (its minted node is gone, or a reused stable attribute it carried
238
+ * no longer exists). The agent must re-`query` against the fresh DOM.
239
+ * - resolve-to-MANY ({@link matched} `> 1`) — the ref matches more than one
240
+ * element (a framework cloned a subtree carrying our minted attribute, or a
241
+ * reused attribute turned out non-unique after a mutation). We refuse to
242
+ * "pick the first", because that is exactly the silent wrong-element click the
243
+ * ref exists to PREVENT.
244
+ *
245
+ * This is STRICTLY SAFER than re-addressing by a positional `.nth(i)`, which
246
+ * SILENTLY clicks whatever now sits at that index. The agent is told "re-query,
247
+ * the page changed" — its natural loop anyway. Mirrors the other typed
248
+ * conditions: the CLI maps {@link code} to a message, and
249
+ * {@link isControllerError} narrows it across a bundle boundary.
250
+ */
251
+ export class StaleRefError extends ControllerError {
252
+ code = 'stale-ref';
253
+ /** The ref locator string that went stale (echoed back so it is visible). */
254
+ ref;
255
+ /** How many elements the ref resolved to (0 = removed/replaced, >1 = ambiguous). */
256
+ matched;
257
+ /** Which verb tried to act on the stale ref (e.g. `click`, `type`). */
258
+ verb;
259
+ constructor(ref, matched, verb, message = matched === 0
260
+ ? `${verb}: the ref ${JSON.stringify(ref)} is STALE — it now matches NO element (the page changed: the element was removed, replaced by a re-render, or the page navigated). Re-run query to get a fresh ref.`
261
+ : `${verb}: the ref ${JSON.stringify(ref)} is AMBIGUOUS — it now matches ${matched} elements (the page changed: a subtree was cloned, or the attribute is no longer unique). Refusing to act on a guessed element; re-run query to get a fresh ref.`, options) {
262
+ super(message, options);
263
+ this.ref = ref;
264
+ this.matched = matched;
265
+ this.verb = verb;
266
+ }
267
+ }
168
268
  /**
169
269
  * Narrow an unknown caught value to a {@link ControllerError}. Prefer this over
170
270
  * `instanceof` at package boundaries: it checks the {@link ControllerError.isControllerError}
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAaH;;;;;;GAMG;AACH,MAAM,OAAgB,eAAgB,SAAQ,KAAK;IAGlD,8EAA8E;IACrE,iBAAiB,GAAG,IAAa,CAAC;IAE3C,YAAY,OAAe,EAAE,OAA2B;QACvD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,sEAAsE;QACtE,yCAAyC;QACzC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;IAC7B,CAAC;CACD;AAED;;;;GAIG;AACH,MAAM,OAAO,yBAA0B,SAAQ,eAAe;IACpD,IAAI,GAAG,wBAAwB,CAAC;IACzC,6DAA6D;IACpD,OAAO,CAAS;IAEzB,YACC,OAAe,EACf,UAAkB,OAAO,OAAO,mCAAmC,EACnE,OAA2B;QAE3B,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACxB,CAAC;CACD;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,6BAA8B,SAAQ,eAAe;IACxD,IAAI,GAAG,4BAA4B,CAAC;IAC7C,kEAAkE;IACzD,UAAU,CAAS;IAE5B,YACC,UAAU,GAAG,YAAY,EACzB,UAAkB,+CAA+C,UAAU,6DAA6D,UAAU,aAAa,UAAU,+GAA+G,EACxR,OAA2B;QAE3B,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC9B,CAAC;CACD;AAED;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,iBAAkB,SAAQ,eAAe;IAC5C,IAAI,GAAG,eAAe,CAAC;IAChC,6EAA6E;IACpE,KAAK,CAAS;IAEvB,YACC,KAAa,EACb,UAAkB,yBAAyB,IAAI,CAAC,SAAS,CACxD,KAAK,CACL,sJAAsJ,EACvJ,OAA2B;QAE3B,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACpB,CAAC;CACD;AAED;;;;;GAKG;AACH,MAAM,OAAO,mBAAoB,SAAQ,eAAe;IAC9C,IAAI,GAAG,iBAAiB,CAAC;IAClC,kDAAkD;IACzC,OAAO,CAAS;IACzB,kEAAkE;IACzD,UAAU,CAAS;IAE5B,YACC,OAAe,EACf,UAAkB,EAClB,UAAkB,QAAQ,OAAO,oDAAoD,UAAU,IAAI,EACnG,OAA2B;QAE3B,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC9B,CAAC;CACD;AAED;;;;;;GAMG;AACH,MAAM,OAAO,sBAAuB,SAAQ,eAAe;IACjD,IAAI,GAAG,qBAAqB,CAAC;IACtC,4EAA4E;IACnE,OAAO,CAAS;IAEzB,YACC,OAAe,EACf,UAAkB,oDAAoD,OAAO,mFAAmF,EAChK,OAA2B;QAE3B,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACxB,CAAC;CACD;AAED;;;;;GAKG;AACH,MAAM,OAAO,oBAAqB,SAAQ,eAAe;IAC/C,IAAI,GAAG,mBAAmB,CAAC;IACpC,qDAAqD;IAC5C,QAAQ,CAAS;IAE1B,YACC,QAAgB,EAChB,UAAkB,+CAA+C,QAAQ,+DAA+D,EACxI,OAA2B;QAE3B,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC1B,CAAC;CACD;AAED;;;;;;;GAOG;AACH,MAAM,OAAO,iBAAkB,SAAQ,eAAe;IAC5C,IAAI,GAAG,gBAAgB,CAAC;IAEjC,YACC,UAAkB,2EAA2E,EAC7F,OAA2B;QAE3B,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACzB,CAAC;CACD;AAED;;;;;GAKG;AACH,MAAM,OAAO,yBAA0B,SAAQ,eAAe;IACpD,IAAI,GAAG,wBAAwB,CAAC;IAEzC,YACC,UAAkB,0DAA0D,EAC5E,OAA2B;QAE3B,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACzB,CAAC;CACD;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC/C,OAAO,CACN,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACb,KAAuC,CAAC,iBAAiB,KAAK,IAAI;QACnE,OAAQ,KAA0B,CAAC,IAAI,KAAK,QAAQ,CACpD,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { type BrowserContext, type Page } from 'playwright';
2
- import type { WebHandsPage, WaitCondition } from './seam.js';
1
+ import { type BrowserContext, type Frame, type Locator, type Page } from 'playwright';
2
+ import type { EvalOptions, WebHandsPage, MouseInput, QueryOptions, QueryRow, Screenshot, ScreenshotOptions, WaitCondition } from './seam.js';
3
3
  /**
4
4
  * The hand-host primitive (Phase 1 of the "hands" prd,
5
5
  * `work/prds/tasked/hands-pluggable-page-capabilities.md`).
@@ -57,6 +57,17 @@ export interface HandContext {
57
57
  readonly pwPage: Page;
58
58
  readonly context: BrowserContext;
59
59
  readonly ensureOpen: () => void;
60
+ /**
61
+ * The managed SCREENSHOTS directory the `screenshot` verb mints PNGs under
62
+ * (Tier-4, prd `broaden-agent-verb-surface`, R3). Resolved by each transport
63
+ * from its home root (`<homeRoot>/screenshots`, beside `profiles/`) via
64
+ * {@link resolveScreenshotsDir}, so the same `root`/`WEBHANDS_HOME` override
65
+ * that isolates profiles in a test isolates screenshots too. The verb creates
66
+ * it lazily on first write and validates any caller `out` override stays under
67
+ * it ({@link ScreenshotPathError}). Carried HERE (not on the seam) so no path
68
+ * policy leaks into the public {@link WebHandsPage} surface (ADR-0003).
69
+ */
70
+ readonly screenshotsDir: string;
60
71
  }
61
72
  /**
62
73
  * What a hand contributes once given its {@link HandContext}: a set of named
@@ -117,7 +128,15 @@ export declare function composePage(ctx: HandContext, hands: readonly Hand[]): C
117
128
  export declare const navigationHand: Hand;
118
129
  /** The `snapshot` verb: the token-cheap a11y view, or `--full` raw DOM. */
119
130
  export declare const snapshotHand: Hand;
120
- /** The `click` + `type` verbs: page interaction by raw locator (ADR-0004). */
131
+ /**
132
+ * The `click` + `type` verbs: page interaction by raw locator (ADR-0004).
133
+ *
134
+ * With `{byRef: true}` the target is a durable `query` {@link QueryRow.ref}: it
135
+ * is resolved through the SAME {@link resolveLocator} but FIRST asserted to match
136
+ * EXACTLY ONE element ({@link assertRefResolvesToOne}), so a stale (zero) or
137
+ * ambiguous (many) ref fails LOUD with a {@link StaleRefError} instead of
138
+ * silently acting on the wrong element — the safety the durable ref exists for.
139
+ */
121
140
  export declare const interactionHand: Hand;
122
141
  /** The `eval` escape hatch: run a JS EXPRESSION in the page, return by value. */
123
142
  export declare const evalHand: Hand;
@@ -130,7 +149,57 @@ export declare const waitHand: Hand;
130
149
  */
131
150
  export declare const cookiesHand: Hand;
132
151
  /**
133
- * webhands' eight built-in verbs as built-in hands, in composition order. Both
152
+ * The Tier-1 read verbs (prd `broaden-agent-verb-surface`, R2): the `query`
153
+ * extraction verb plus the thin state shorthands `count` / `exists` /
154
+ * `isVisible` / `getAttribute`. All five address element(s) by the SAME raw
155
+ * Playwright locator expression the other verbs use, resolved through the ONE
156
+ * existing {@link resolveLocator} (so a `frameLocator(...)` same-origin frame
157
+ * hop in the string Just Works, and there is no parallel addressing scheme —
158
+ * R1). They are pure READS: no page mutation.
159
+ *
160
+ * `query` returns one row per match carrying EXACTLY the requested fields (R2);
161
+ * the state verbs are computed over the same machinery (see {@link queryRows}
162
+ * and the per-verb bodies). Read values cross by structured clone, the same
163
+ * contract as `eval` (ADR-0003).
164
+ */
165
+ export declare const queryHand: Hand;
166
+ /**
167
+ * The Tier-2 rich INPUT verbs (prd `broaden-agent-verb-surface`, stories 8-12):
168
+ * `press` / `hover` / `select` / `scroll` / `drag`. These lift page-level
169
+ * Playwright actions a hand already has on `pwPage` (`keyboard.press`,
170
+ * `hover`, `selectOption`, `mouse.wheel`/`scrollIntoViewIfNeeded`, `dragTo`) up
171
+ * to the agent verb seam so a seam-only agent can drive a browser game or a
172
+ * richer form, not just `click`/`type`.
173
+ *
174
+ * Every locator-addressing form resolves through the SAME single
175
+ * {@link resolveLocator} the other verbs use (so a same-origin `frameLocator(...)`
176
+ * hop in the string Just Works — no parallel addressing scheme, R1). Keys are
177
+ * strings, offsets are numbers, locators are strings: nothing Playwright-shaped
178
+ * crosses the seam (ADR-0003).
179
+ */
180
+ export declare const inputHand: Hand;
181
+ /**
182
+ * The Tier-4 COORDINATE + SCREENSHOT hand (prd `broaden-agent-verb-surface`,
183
+ * R3; stories 17-19): the `mouse` coordinate-input verb and the `screenshot`
184
+ * path-returning verb, the look-then-click pair that lets a seam-only agent
185
+ * handle the VISION/TILE captcha family and any visual task.
186
+ *
187
+ * The seam stays ADR-0003-clean (as amended by the Tier-4 ADR) by passing ONLY
188
+ * numbers + a string enum (`mouse`) and returning ONLY a file PATH + dimensions
189
+ * (`screenshot`): NO image bytes and NO Playwright/CDP type cross the seam.
190
+ *
191
+ * - `mouse` drives Playwright `page.mouse` at VIEWPORT CSS-pixels (NOT OS-level
192
+ * input). A VIEWPORT screenshot's pixels map directly to these coordinates
193
+ * (the look-then-click contract); a FULL-PAGE shot does not.
194
+ * - `screenshot` MINTS a PNG under the managed {@link HandContext.screenshotsDir}
195
+ * and returns its path. The `element` scope clips to a locator (resolved
196
+ * through the SAME {@link resolveLocator}, so a cross-origin `frameLocator(...)`
197
+ * widget shot Just Works). A caller `out` override is validated to stay under
198
+ * the managed dir ({@link ScreenshotPathError}).
199
+ */
200
+ export declare const coordinateHand: Hand;
201
+ /**
202
+ * webhands' built-in verbs as built-in hands, in composition order. Both
134
203
  * Playwright transports compose THIS exact set, so the verb surface is
135
204
  * identical across launch and attach (the only legitimate difference is the
136
205
  * per-transport SESSION LIFECYCLE, which is not a hand's concern).
@@ -181,6 +250,53 @@ export declare function composeWithHands(ctx: HandContext, extraHands: readonly
181
250
  * verb behaviour stays identical (no parallel second implementation).
182
251
  */
183
252
  export declare function waitFor(page: Page, condition: WaitCondition): Promise<void>;
253
+ /**
254
+ * Run the `eval` verb against a Playwright page (PRD story 9; frame scope from
255
+ * prd `broaden-agent-verb-surface`, Tier-3), shared by both Playwright
256
+ * transports (via the built-in eval hand) so the verb behaves identically (no
257
+ * parallel second implementation).
258
+ *
259
+ * With no `frame`, this is the top-document escape hatch: Playwright's
260
+ * `evaluate` IS the seam's serialization contract (see {@link WebHandsPage.eval}):
261
+ * it passes a string as an expression, awaits a returned Promise, and
262
+ * structurally clones the result out of the page by VALUE. That clone is richer
263
+ * than JSON: it preserves NaN/Infinity/BigInt and circular structures (back-refs
264
+ * become a `[Circular]` marker), yields `undefined` for functions/symbols, and
265
+ * returns an opaque preview string for a live host object (a DOM node never
266
+ * crosses the process boundary). A page-side throw rejects. We pass it straight
267
+ * through rather than re-encode it: wrapping the value in a transport-specific
268
+ * envelope would invent a dialect the seam deliberately avoids. The thrown error
269
+ * is a plain `Error`, so no Playwright/CDP type leaks across the seam (ADR-0003).
270
+ *
271
+ * With a `frame` selector, the SAME structured-clone contract holds, but the
272
+ * expression runs in the named SAME-ORIGIN child frame (resolved through the
273
+ * single {@link resolveSameOriginFrame}, which reuses the same
274
+ * {@link resolveLocator} the locator-taking verbs use). A cross-origin frame
275
+ * REJECTS with a typed {@link CrossOriginFrameError} (see that resolver).
276
+ */
277
+ export declare function evalExpression(page: Page, expression: string, options?: EvalOptions): Promise<unknown>;
278
+ /**
279
+ * Resolve a `frame` SELECTOR string to a live, SAME-ORIGIN Playwright
280
+ * {@link Frame} for a frame-scoped `eval` (prd `broaden-agent-verb-surface`,
281
+ * Tier-3, R1). This is the SINGLE frame resolver: it reuses the very same
282
+ * {@link resolveLocator} the locator-taking verbs use (a `frameLocator(...)`
283
+ * over the selector), then walks the iframe element handle to its content
284
+ * frame — there is no parallel frame-addressing scheme.
285
+ *
286
+ * SAME-ORIGIN ONLY, enforced LOUD. Playwright will happily `evaluate` inside a
287
+ * CROSS-ORIGIN OOPIF (it attaches out-of-band), so a cross-origin frame would
288
+ * NOT throw on its own — it would silently succeed, which is exactly the
289
+ * contract violation this verb forbids (page-world JS cannot cross a security
290
+ * boundary; the seam is same-origin only). So we DETECT cross-origin by
291
+ * comparing the frame's origin to the page's main-frame origin and reject with a
292
+ * typed {@link CrossOriginFrameError} when they differ, never returning a frame
293
+ * the page world could not legitimately reach.
294
+ *
295
+ * Failure modes are loud/typed: a selector that matches NO iframe element
296
+ * rejects (the locator resolves nothing); a matched frame with no content frame
297
+ * rejects; a cross-origin frame rejects with {@link CrossOriginFrameError}.
298
+ */
299
+ export declare function resolveSameOriginFrame(page: Page, selector: string): Promise<Frame>;
184
300
  /**
185
301
  * Resolve a raw Playwright locator EXPRESSION (ADR-0004) against the page. The
186
302
  * verb surface passes locator expressions like `getByRole('button', …)`; we
@@ -191,7 +307,7 @@ export declare function waitFor(page: Page, condition: WaitCondition): Promise<v
191
307
  * One resolution path for both transports (via the built-in interaction/wait
192
308
  * hands), so there is no parallel addressing scheme.
193
309
  */
194
- export declare function resolveLocator(page: Page, expression: string): import("playwright").Locator;
310
+ export declare function resolveLocator(page: Page, expression: string): Locator;
195
311
  /**
196
312
  * Run the `click` verb against a Playwright page (PRD story 8), shared by both
197
313
  * Playwright transports (via the built-in interaction hand) so the verb behaves
@@ -212,6 +328,83 @@ export declare function resolveLocator(page: Page, expression: string): import("
212
328
  * bad locator) surfaces its timeout quickly instead of hanging the dispatch on
213
329
  * Playwright's 30s default — the dispatch escape is for elements that EXIST but
214
330
  * are not actionable (hidden custom inputs), not for absent ones.
331
+ *
332
+ * The happy-path click passes `noWaitAfter: true` on purpose. Playwright's
333
+ * `Locator.click()` normally clicks AND THEN auto-waits for any navigation the
334
+ * click scheduled to finish, and that post-click wait counts against the same
335
+ * timeout. A real submit button whose navigation takes longer than
336
+ * {@link NORMAL_CLICK_TIMEOUT_MS} would therefore have its (already-performed)
337
+ * click reported as a `TimeoutError` and be wrongly routed to the dispatch
338
+ * escape, which then re-clicks a page that is already navigating away. We only
339
+ * want the short budget to measure ACTIONABILITY (can we click it?), not how
340
+ * long the resulting navigation takes — `noWaitAfter` returns as soon as the
341
+ * click is performed, so a slow-but-successful submit no longer trips the
342
+ * fallback. A genuinely non-actionable hidden input still cannot be clicked
343
+ * within the budget and still falls through to `dispatchEvent` as before.
215
344
  */
216
345
  export declare function clickLocator(page: Page, expression: string): Promise<void>;
346
+ /**
347
+ * Run the `query` verb (prd `broaden-agent-verb-surface`, R2) against a
348
+ * Playwright page: resolve the locator EXPRESSION through the SINGLE existing
349
+ * {@link resolveLocator} (so a same-origin `frameLocator(...)` hop in the string
350
+ * Just Works), then return ONE ROW PER MATCH carrying EXACTLY the requested
351
+ * fields and nothing else.
352
+ *
353
+ * The split is LOUD and never auto-detected:
354
+ * - `attrs[name]` is the element's `getAttribute(name)` (the markup value;
355
+ * `null` if absent).
356
+ * - `props[name]` is the live `el[name]` JS property (runtime state), read in
357
+ * one page-world `evaluate` over the element so the value is structurally
358
+ * cloned out by VALUE — the SAME serialization contract `eval` documents
359
+ * (ADR-0003: no Playwright/CDP type leak; richer than JSON).
360
+ * - `pw.visible` / `pw.bbox` are the closed Playwright-locator extras
361
+ * (`isVisible()` / `boundingBox()`), the only facts not expressible as an
362
+ * attribute or a property. `bbox` is in VIEWPORT CSS-pixels.
363
+ *
364
+ * `limit` bounds the row count. With no fields requested every row is an empty
365
+ * object (the caller asked for nothing; R2). Each row is built independently so
366
+ * a per-element read failure is the page's own throw, surfaced faithfully like
367
+ * `eval` (no silent swallow).
368
+ */
369
+ export declare function queryRows(page: Page, expression: string, options?: QueryOptions): Promise<QueryRow[]>;
370
+ /**
371
+ * Resolve a durable `query` `ref` and assert it matches EXACTLY ONE element,
372
+ * else throw a typed {@link StaleRefError} (resolve-to-ZERO = removed/replaced;
373
+ * resolve-to-MANY = a cloned subtree / non-unique attribute). The loud-stale
374
+ * guard `click`/`type` run BEFORE acting when `{byRef: true}`, so a stale or
375
+ * ambiguous ref NEVER silently acts on the wrong element (the safety a ref has
376
+ * over a positional `.nth(i)`). Resolved through the SAME {@link resolveLocator}
377
+ * the verbs already use — no parallel addressing path.
378
+ */
379
+ export declare function assertRefResolvesToOne(page: Page, ref: string, verb: string): Promise<void>;
380
+ /**
381
+ * Run the `mouse` verb (prd `broaden-agent-verb-surface`, Tier-4, R3) against a
382
+ * Playwright page: drive `page.mouse` at the given VIEWPORT CSS-pixel
383
+ * coordinate. Viewport-relative, NOT OS-level input — the same coordinate frame
384
+ * a VIEWPORT `screenshot` is captured in, so a pixel an agent saw maps directly
385
+ * to the click. Shared by both transports (via the coordinate hand) so the verb
386
+ * behaves identically. Plain numbers + a string enum only (ADR-0003 as amended).
387
+ */
388
+ export declare function doMouse(page: Page, input: MouseInput): Promise<void>;
389
+ /**
390
+ * Run the `screenshot` verb (prd `broaden-agent-verb-surface`, Tier-4, R3;
391
+ * stories 17-19) against a Playwright page: capture the requested SCOPE to a PNG
392
+ * FILE under the managed `screenshotsDir` and return `{path, width, height}` —
393
+ * NEVER image bytes (the load-bearing ADR-0003-as-amended choice). Shared by
394
+ * both transports (via the coordinate hand).
395
+ *
396
+ * Scopes:
397
+ * - `viewport` (default) — the visible viewport, COORDINATE-MATCHED to `mouse`.
398
+ * - `full` — the whole scrollable page (`fullPage: true`), NOT coordinate-matched.
399
+ * - `element` — clipped to the locator's element (REQUIRED; resolved through the
400
+ * SAME {@link resolveLocator}, so a `frameLocator(...)` frame widget works even
401
+ * cross-origin). A missing locator for `element`, or a stray locator on a
402
+ * non-`element` scope, is a LOUD validation error (mirrors `wait`).
403
+ *
404
+ * The PNG is written by Playwright to a path webhands MINTS under the managed
405
+ * dir (or a caller `out` override VALIDATED to stay under it, else
406
+ * {@link ScreenshotPathError}). We read the PNG's IHDR for the real pixel
407
+ * dimensions (so the number is the image's, not an assumed viewport size).
408
+ */
409
+ export declare function takeScreenshot(page: Page, screenshotsDir: string, options?: ScreenshotOptions): Promise<Screenshot>;
217
410
  //# sourceMappingURL=hand-host.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hand-host.d.ts","sourceRoot":"","sources":["../src/hand-host.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,cAAc,EAAE,KAAK,IAAI,EAAC,MAAM,YAAY,CAAC;AAC9E,OAAO,KAAK,EAEX,YAAY,EAGZ,aAAa,EACb,MAAM,WAAW,CAAC;AAEnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,IAAI,CAAC;CAChC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC9C;AAED;;;;;GAKG;AACH,MAAM,MAAM,IAAI,GAAG,CAAC,GAAG,EAAE,WAAW,KAAK,gBAAgB,CAAC;AAE1D;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B;;;;;;;OAOG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAC1B,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,SAAS,IAAI,EAAE,GACpB,aAAa,CAgCf;AAsDD,8EAA8E;AAC9E,eAAO,MAAM,cAAc,EAAE,IAe3B,CAAC;AAEH,2EAA2E;AAC3E,eAAO,MAAM,YAAY,EAAE,IAyBzB,CAAC;AAEH,8EAA8E;AAC9E,eAAO,MAAM,eAAe,EAAE,IAW5B,CAAC;AAEH,iFAAiF;AACjF,eAAO,MAAM,QAAQ,EAAE,IAoBrB,CAAC;AAEH,iFAAiF;AACjF,eAAO,MAAM,QAAQ,EAAE,IAOrB,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,IAYxB,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,IAAI,EAOzC,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,WAAW,GAAG,aAAa,CAElE;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC/B,GAAG,EAAE,WAAW,EAChB,UAAU,EAAE,SAAS,IAAI,EAAE,GACzB,aAAa,CAEf;AAOD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,OAAO,CAC5B,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,aAAa,GACtB,OAAO,CAAC,IAAI,CAAC,CAaf;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,gCAO5D;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,YAAY,CACjC,IAAI,EAAE,IAAI,EACV,UAAU,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAYf"}
1
+ {"version":3,"file":"hand-host.d.ts","sourceRoot":"","sources":["../src/hand-host.ts"],"names":[],"mappings":"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"}