@webhands/core 0.1.0 → 0.3.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 (55) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +177 -0
  3. package/dist/cookies-export.d.ts +5 -5
  4. package/dist/cookies-export.d.ts.map +1 -1
  5. package/dist/cookies-export.js +4 -4
  6. package/dist/errors.d.ts +24 -1
  7. package/dist/errors.d.ts.map +1 -1
  8. package/dist/errors.js +24 -0
  9. package/dist/errors.js.map +1 -1
  10. package/dist/hand-host.d.ts +217 -0
  11. package/dist/hand-host.d.ts.map +1 -0
  12. package/dist/hand-host.js +351 -0
  13. package/dist/hand-host.js.map +1 -0
  14. package/dist/hand-loading.d.ts +128 -0
  15. package/dist/hand-loading.d.ts.map +1 -0
  16. package/dist/hand-loading.js +143 -0
  17. package/dist/hand-loading.js.map +1 -0
  18. package/dist/index.d.ts +6 -4
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +4 -3
  21. package/dist/index.js.map +1 -1
  22. package/dist/playwright-attach-transport.d.ts +9 -0
  23. package/dist/playwright-attach-transport.d.ts.map +1 -1
  24. package/dist/playwright-attach-transport.js +53 -91
  25. package/dist/playwright-attach-transport.js.map +1 -1
  26. package/dist/playwright-launch-transport.d.ts +81 -62
  27. package/dist/playwright-launch-transport.d.ts.map +1 -1
  28. package/dist/playwright-launch-transport.js +143 -210
  29. package/dist/playwright-launch-transport.js.map +1 -1
  30. package/dist/remote-session.d.ts +12 -2
  31. package/dist/remote-session.d.ts.map +1 -1
  32. package/dist/remote-session.js +37 -6
  33. package/dist/remote-session.js.map +1 -1
  34. package/dist/seam.d.ts +13 -5
  35. package/dist/seam.d.ts.map +1 -1
  36. package/dist/session-rpc.d.ts +76 -12
  37. package/dist/session-rpc.d.ts.map +1 -1
  38. package/dist/session-rpc.js +76 -8
  39. package/dist/session-rpc.js.map +1 -1
  40. package/dist/stub-transport.d.ts +2 -2
  41. package/dist/stub-transport.d.ts.map +1 -1
  42. package/dist/stub-transport.js +11 -0
  43. package/dist/stub-transport.js.map +1 -1
  44. package/package.json +24 -2
  45. package/src/cookies-export.ts +5 -5
  46. package/src/errors.ts +31 -0
  47. package/src/hand-host.ts +511 -0
  48. package/src/hand-loading.ts +254 -0
  49. package/src/index.ts +24 -2
  50. package/src/playwright-attach-transport.ts +65 -119
  51. package/src/playwright-launch-transport.ts +235 -249
  52. package/src/remote-session.ts +43 -5
  53. package/src/seam.ts +13 -5
  54. package/src/session-rpc.ts +121 -11
  55. package/src/stub-transport.ts +15 -3
package/dist/index.d.ts CHANGED
@@ -1,15 +1,17 @@
1
- export type { Cookie, Driver, LocatorString, OpenTarget, Page, Session, Snapshot, SnapshotOptions, SnapshotView, Transport, WaitCondition, } from './seam.js';
1
+ export type { Cookie, Driver, LocatorString, OpenTarget, WebHandsPage, Session, Snapshot, SnapshotOptions, SnapshotView, Transport, WaitCondition, } from './seam.js';
2
2
  export { locator } from './seam.js';
3
3
  export { serializeCookies, deserializeCookies, COOKIES_EXPORT_VERSION, type CookiesExport, } from './cookies-export.js';
4
4
  export { StubTransport, type StubCall } from './stub-transport.js';
5
- export { PlaywrightLaunchTransport } from './playwright-launch-transport.js';
5
+ export type { Hand, HandContext, HandContribution } from './hand-host.js';
6
+ export { readHandsConfig, normalizeConfig, loadHands, HandLoadError, HANDS_CONFIG_FILENAME, type HandEntry, type HandsConfig, type LoadedHand, type LoadHandsOptions, } from './hand-loading.js';
7
+ export { PlaywrightLaunchTransport, type PlaywrightLaunchTransportOptions, type StealthChromiumImporter, } from './playwright-launch-transport.js';
6
8
  export { PlaywrightAttachTransport } from './playwright-attach-transport.js';
7
9
  export { setupProfile, buildPrompt, type PromptSink, type SetupProfileOptions, type SetupProfileResult, } from './setup-profile.js';
8
- export { ControllerError, MissingBrowserBinaryError, MissingProfileError, AttachNotChromiumError, AttachNoContextError, NoLiveServerError, SessionAlreadyActiveError, isControllerError, type ControllerErrorCode, } from './errors.js';
10
+ export { ControllerError, MissingBrowserBinaryError, MissingStealthDependencyError, MissingProfileError, AttachNotChromiumError, AttachNoContextError, NoLiveServerError, SessionAlreadyActiveError, isControllerError, type ControllerErrorCode, } from './errors.js';
9
11
  export { resolveSessionEndpointPath, writeSessionEndpoint, readSessionEndpoint, clearSessionEndpoint, SESSION_ENDPOINT_FILENAME, type SessionEndpoint, } from './session-endpoint.js';
10
12
  export { startSessionServer, sessionAlreadyActive, type SessionServerOptions, type RunningSessionServer, } from './session-server.js';
11
13
  export { connectRemoteSession } from './remote-session.js';
12
- export { SESSION_RPC_PATH, applySessionRpc, makeRpcPage, type SessionRpcRequest, type SessionRpcResponse, } from './session-rpc.js';
14
+ export { SESSION_RPC_PATH, applySessionRpc, makeRpcPage, callHandVerb, type SessionRpcRequest, type SessionRpcBuiltInRequest, type SessionRpcHandRequest, type SessionRpcResponse, } from './session-rpc.js';
13
15
  export { resolveHomeRoot, resolveProfileLocation, CONTROLLER_HOME_ENV, DEFAULT_HOME_DIRNAME, PROFILES_DIRNAME, type ProfileLocation, type ProfileLocationOptions, } from './profile-location.js';
14
16
  export { startFixtureServer, type FixtureServer, } from './test-fixtures/fixture-server.js';
15
17
  export { FIXTURE_PAGES } from './test-fixtures/fixture-pages.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,MAAM,EACN,MAAM,EACN,aAAa,EACb,UAAU,EACV,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,SAAS,EACT,aAAa,GACb,MAAM,WAAW,CAAC;AACnB,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAElC,OAAO,EACN,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,EACtB,KAAK,aAAa,GAClB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAC,aAAa,EAAE,KAAK,QAAQ,EAAC,MAAM,qBAAqB,CAAC;AAEjE,OAAO,EAAC,yBAAyB,EAAC,MAAM,kCAAkC,CAAC;AAE3E,OAAO,EAAC,yBAAyB,EAAC,MAAM,kCAAkC,CAAC;AAE3E,OAAO,EACN,YAAY,EACZ,WAAW,EACX,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,GACvB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACN,eAAe,EACf,yBAAyB,EACzB,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,iBAAiB,EACjB,yBAAyB,EACzB,iBAAiB,EACjB,KAAK,mBAAmB,GACxB,MAAM,aAAa,CAAC;AAErB,OAAO,EACN,0BAA0B,EAC1B,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,yBAAyB,EACzB,KAAK,eAAe,GACpB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACN,kBAAkB,EAClB,oBAAoB,EACpB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,GACzB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAC,oBAAoB,EAAC,MAAM,qBAAqB,CAAC;AAEzD,OAAO,EACN,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,GACvB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACN,eAAe,EACf,sBAAsB,EACtB,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,KAAK,eAAe,EACpB,KAAK,sBAAsB,GAC3B,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACN,kBAAkB,EAClB,KAAK,aAAa,GAClB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAC,aAAa,EAAC,MAAM,kCAAkC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,MAAM,EACN,MAAM,EACN,aAAa,EACb,UAAU,EACV,YAAY,EACZ,OAAO,EACP,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,SAAS,EACT,aAAa,GACb,MAAM,WAAW,CAAC;AACnB,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAElC,OAAO,EACN,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,EACtB,KAAK,aAAa,GAClB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAC,aAAa,EAAE,KAAK,QAAQ,EAAC,MAAM,qBAAqB,CAAC;AAEjE,YAAY,EAAC,IAAI,EAAE,WAAW,EAAE,gBAAgB,EAAC,MAAM,gBAAgB,CAAC;AAExE,OAAO,EACN,eAAe,EACf,eAAe,EACf,SAAS,EACT,aAAa,EACb,qBAAqB,EACrB,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,gBAAgB,GACrB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACN,yBAAyB,EACzB,KAAK,gCAAgC,EACrC,KAAK,uBAAuB,GAC5B,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EAAC,yBAAyB,EAAC,MAAM,kCAAkC,CAAC;AAE3E,OAAO,EACN,YAAY,EACZ,WAAW,EACX,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,GACvB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACN,eAAe,EACf,yBAAyB,EACzB,6BAA6B,EAC7B,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,iBAAiB,EACjB,yBAAyB,EACzB,iBAAiB,EACjB,KAAK,mBAAmB,GACxB,MAAM,aAAa,CAAC;AAErB,OAAO,EACN,0BAA0B,EAC1B,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,yBAAyB,EACzB,KAAK,eAAe,GACpB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACN,kBAAkB,EAClB,oBAAoB,EACpB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,GACzB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAC,oBAAoB,EAAC,MAAM,qBAAqB,CAAC;AAEzD,OAAO,EACN,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,YAAY,EACZ,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,EAC7B,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,GACvB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACN,eAAe,EACf,sBAAsB,EACtB,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,KAAK,eAAe,EACpB,KAAK,sBAAsB,GAC3B,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACN,kBAAkB,EAClB,KAAK,aAAa,GAClB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAC,aAAa,EAAC,MAAM,kCAAkC,CAAC"}
package/dist/index.js CHANGED
@@ -1,14 +1,15 @@
1
1
  export { locator } from './seam.js';
2
2
  export { serializeCookies, deserializeCookies, COOKIES_EXPORT_VERSION, } from './cookies-export.js';
3
3
  export { StubTransport } from './stub-transport.js';
4
- export { PlaywrightLaunchTransport } from './playwright-launch-transport.js';
4
+ export { readHandsConfig, normalizeConfig, loadHands, HandLoadError, HANDS_CONFIG_FILENAME, } from './hand-loading.js';
5
+ export { PlaywrightLaunchTransport, } from './playwright-launch-transport.js';
5
6
  export { PlaywrightAttachTransport } from './playwright-attach-transport.js';
6
7
  export { setupProfile, buildPrompt, } from './setup-profile.js';
7
- export { ControllerError, MissingBrowserBinaryError, MissingProfileError, AttachNotChromiumError, AttachNoContextError, NoLiveServerError, SessionAlreadyActiveError, isControllerError, } from './errors.js';
8
+ export { ControllerError, MissingBrowserBinaryError, MissingStealthDependencyError, MissingProfileError, AttachNotChromiumError, AttachNoContextError, NoLiveServerError, SessionAlreadyActiveError, isControllerError, } from './errors.js';
8
9
  export { resolveSessionEndpointPath, writeSessionEndpoint, readSessionEndpoint, clearSessionEndpoint, SESSION_ENDPOINT_FILENAME, } from './session-endpoint.js';
9
10
  export { startSessionServer, sessionAlreadyActive, } from './session-server.js';
10
11
  export { connectRemoteSession } from './remote-session.js';
11
- export { SESSION_RPC_PATH, applySessionRpc, makeRpcPage, } from './session-rpc.js';
12
+ export { SESSION_RPC_PATH, applySessionRpc, makeRpcPage, callHandVerb, } from './session-rpc.js';
12
13
  export { resolveHomeRoot, resolveProfileLocation, CONTROLLER_HOME_ENV, DEFAULT_HOME_DIRNAME, PROFILES_DIRNAME, } from './profile-location.js';
13
14
  export { startFixtureServer, } from './test-fixtures/fixture-server.js';
14
15
  export { FIXTURE_PAGES } from './test-fixtures/fixture-pages.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAElC,OAAO,EACN,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,GAEtB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAC,aAAa,EAAgB,MAAM,qBAAqB,CAAC;AAEjE,OAAO,EAAC,yBAAyB,EAAC,MAAM,kCAAkC,CAAC;AAE3E,OAAO,EAAC,yBAAyB,EAAC,MAAM,kCAAkC,CAAC;AAE3E,OAAO,EACN,YAAY,EACZ,WAAW,GAIX,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACN,eAAe,EACf,yBAAyB,EACzB,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,iBAAiB,EACjB,yBAAyB,EACzB,iBAAiB,GAEjB,MAAM,aAAa,CAAC;AAErB,OAAO,EACN,0BAA0B,EAC1B,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,yBAAyB,GAEzB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACN,kBAAkB,EAClB,oBAAoB,GAGpB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAC,oBAAoB,EAAC,MAAM,qBAAqB,CAAC;AAEzD,OAAO,EACN,gBAAgB,EAChB,eAAe,EACf,WAAW,GAGX,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACN,eAAe,EACf,sBAAsB,EACtB,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,GAGhB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACN,kBAAkB,GAElB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAC,aAAa,EAAC,MAAM,kCAAkC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAElC,OAAO,EACN,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,GAEtB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAC,aAAa,EAAgB,MAAM,qBAAqB,CAAC;AAIjE,OAAO,EACN,eAAe,EACf,eAAe,EACf,SAAS,EACT,aAAa,EACb,qBAAqB,GAKrB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACN,yBAAyB,GAGzB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EAAC,yBAAyB,EAAC,MAAM,kCAAkC,CAAC;AAE3E,OAAO,EACN,YAAY,EACZ,WAAW,GAIX,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACN,eAAe,EACf,yBAAyB,EACzB,6BAA6B,EAC7B,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,iBAAiB,EACjB,yBAAyB,EACzB,iBAAiB,GAEjB,MAAM,aAAa,CAAC;AAErB,OAAO,EACN,0BAA0B,EAC1B,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,yBAAyB,GAEzB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACN,kBAAkB,EAClB,oBAAoB,GAGpB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAC,oBAAoB,EAAC,MAAM,qBAAqB,CAAC;AAEzD,OAAO,EACN,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,YAAY,GAKZ,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACN,eAAe,EACf,sBAAsB,EACtB,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,GAGhB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACN,kBAAkB,GAElB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAC,aAAa,EAAC,MAAM,kCAAkC,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { type Hand } from './hand-host.js';
1
2
  import type { OpenTarget, Session, Transport } from './seam.js';
2
3
  /**
3
4
  * The `attach` concrete transport: connect (`chromium.connectOverCDP`) to a
@@ -23,6 +24,14 @@ import type { OpenTarget, Session, Transport } from './seam.js';
23
24
  * running one.
24
25
  */
25
26
  export declare class PlaywrightAttachTransport implements Transport {
27
+ #private;
28
+ /**
29
+ * @param hands explicitly-loaded third-party hands to compose alongside the
30
+ * built-ins (Phase 2, ADR-0007). These come from {@link loadHands} against
31
+ * the operator's explicit config; the transport does NOT discover them. Omit
32
+ * for the built-ins-only surface.
33
+ */
34
+ constructor(hands?: readonly Hand[]);
26
35
  open(target: OpenTarget): Promise<Session>;
27
36
  }
28
37
  //# sourceMappingURL=playwright-attach-transport.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"playwright-attach-transport.d.ts","sourceRoot":"","sources":["../src/playwright-attach-transport.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAEX,UAAU,EAEV,OAAO,EAGP,SAAS,EAET,MAAM,WAAW,CAAC;AAEnB;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,yBAA0B,YAAW,SAAS;IACpD,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC;CA0ChD"}
1
+ {"version":3,"file":"playwright-attach-transport.d.ts","sourceRoot":"","sources":["../src/playwright-attach-transport.ts"],"names":[],"mappings":"AAOA,OAAO,EAAmB,KAAK,IAAI,EAAmB,MAAM,gBAAgB,CAAC;AAC7E,OAAO,KAAK,EAAC,UAAU,EAAE,OAAO,EAAE,SAAS,EAAC,MAAM,WAAW,CAAC;AAE9D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,yBAA0B,YAAW,SAAS;;IAG1D;;;;;OAKG;gBACS,KAAK,GAAE,SAAS,IAAI,EAAO;IAIjC,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC;CA0ChD"}
@@ -1,6 +1,6 @@
1
1
  import { chromium, } from 'playwright';
2
2
  import { AttachNoContextError, AttachNotChromiumError } from './errors.js';
3
- import { clickLocator, resolveLocator, waitFor, } from './playwright-launch-transport.js';
3
+ import { composeWithHands } from './hand-host.js';
4
4
  /**
5
5
  * The `attach` concrete transport: connect (`chromium.connectOverCDP`) to a
6
6
  * browser the USER already started with remote debugging enabled, and reuse the
@@ -25,6 +25,16 @@ import { clickLocator, resolveLocator, waitFor, } from './playwright-launch-tran
25
25
  * running one.
26
26
  */
27
27
  export class PlaywrightAttachTransport {
28
+ #hands;
29
+ /**
30
+ * @param hands explicitly-loaded third-party hands to compose alongside the
31
+ * built-ins (Phase 2, ADR-0007). These come from {@link loadHands} against
32
+ * the operator's explicit config; the transport does NOT discover them. Omit
33
+ * for the built-ins-only surface.
34
+ */
35
+ constructor(hands = []) {
36
+ this.#hands = hands;
37
+ }
28
38
  async open(target) {
29
39
  if (target.mode !== 'attach') {
30
40
  throw new Error(`PlaywrightAttachTransport only handles 'attach'; ` +
@@ -52,7 +62,7 @@ export class PlaywrightAttachTransport {
52
62
  // browser exposes a context with no page yet (single active session in
53
63
  // v1, PRD Out of Scope).
54
64
  const pwPage = context.pages()[0] ?? (await context.newPage());
55
- return makeAttachedSession(browser, pwPage);
65
+ return makeAttachedSession(browser, pwPage, this.#hands);
56
66
  }
57
67
  catch (cause) {
58
68
  // On any open-time refusal, disconnect from the user's browser without
@@ -66,13 +76,19 @@ export class PlaywrightAttachTransport {
66
76
  /**
67
77
  * Wrap a CDP-attached browser into the seam's {@link Session}.
68
78
  *
69
- * `close()` DISCONNECTS the controller from the user's browser; it must not
70
- * kill the browser the user started (`Browser.close()` on a `connectOverCDP`
71
- * connection detaches rather than terminating the remote process). We resolve
72
- * cookies through the reused context so they reflect the live, authenticated
73
- * session.
79
+ * The VERB surface comes from the shared hand-host ({@link composeBuiltInPage}),
80
+ * the SAME single composition the launch transport uses (no duplicated
81
+ * page-object literal). Cookies resolve through the reused context (derived here
82
+ * via `pwPage.context()`) so they reflect the live, authenticated session.
83
+ *
84
+ * Only the SESSION LIFECYCLE is per-transport: this transport listens on the
85
+ * browser's `'disconnected'` event and its `close()` calls `browser.close()`,
86
+ * which DISCONNECTS the controller from the user's browser WITHOUT killing it
87
+ * (a `connectOverCDP` connection detaches rather than terminating the remote
88
+ * process, ADR-0002) — the opposite of the launch transport, which kills the
89
+ * browser it spawned.
74
90
  */
75
- function makeAttachedSession(browser, pwPage) {
91
+ function makeAttachedSession(browser, pwPage, extraHands) {
76
92
  const context = pwPage.context();
77
93
  let closed = false;
78
94
  const ensureOpen = () => {
@@ -80,96 +96,42 @@ function makeAttachedSession(browser, pwPage) {
80
96
  throw new Error('session is closed');
81
97
  }
82
98
  };
83
- const page = {
84
- async navigate(url) {
85
- ensureOpen();
86
- // "Settled" = the `load` event; XHR/JS-rendered content that appears
87
- // after load is the `wait` verb's job. Same rationale (and the
88
- // no-`networkidle` reasoning) as the launch transport's `navigate`.
89
- await pwPage.goto(url, { waitUntil: 'load' });
90
- },
91
- async snapshot(options) {
92
- ensureOpen();
93
- const url = pwPage.url();
94
- if (options?.full === true) {
95
- const content = await pwPage.evaluate(() => document.documentElement.outerHTML);
96
- return { url, view: 'full', content };
97
- }
98
- // Default: the token-cheap accessibility tree + visible text with stable
99
- // `[ref=...]` refs (see the launch transport and `Snapshot` for the
100
- // rationale; the string crosses the seam as opaque, transport-neutral
101
- // text, ADR-0003).
102
- const content = await pwPage.ariaSnapshot({ mode: 'ai' });
103
- return { url, view: 'accessibility', content };
104
- },
105
- // `resolveLocator`/`clickLocator`/`waitFor` are imported from the launch
106
- // transport so both transports resolve locators and run the verbs through
107
- // ONE path (no parallel addressing scheme; the forward-note).
108
- async click(t) {
109
- ensureOpen();
110
- // Shared `clickLocator`: normal actionability-checked click with the
111
- // hidden-element dispatch fallback (PRD story 8), identical to launch.
112
- await clickLocator(pwPage, t);
113
- },
114
- async type(t, text) {
115
- ensureOpen();
116
- await resolveLocator(pwPage, t).fill(text);
117
- },
118
- async eval(expression) {
119
- ensureOpen();
120
- return pwPage.evaluate(expression);
121
- },
122
- async wait(condition) {
123
- ensureOpen();
124
- // Identical to the launch transport (shared `waitFor`): selector /
125
- // navigation / timeout, so the verb behaves the same on both.
126
- await waitFor(pwPage, condition);
127
- },
128
- async cookies() {
129
- ensureOpen();
130
- const raw = await context.cookies();
131
- return raw.map(toSeamCookie);
132
- },
133
- async setCookies(cookies) {
134
- ensureOpen();
135
- await context.addCookies(cookies.map(fromSeamCookie));
136
- },
99
+ // Resolves when the session ends: either the user's browser goes away
100
+ // (Playwright fires 'disconnected' on a connectOverCDP browser) or our own
101
+ // close() disconnects. Lets a caller block until the session is gone.
102
+ let resolveClosed;
103
+ const closedSignal = new Promise((resolve) => {
104
+ resolveClosed = resolve;
105
+ });
106
+ const markClosed = () => {
107
+ if (closed)
108
+ return;
109
+ closed = true;
110
+ resolveClosed();
137
111
  };
112
+ browser.on('disconnected', markClosed);
113
+ // Build the verb surface from the built-in hands over a live hand-context —
114
+ // the same shared host the launch transport uses, so the verbs behave
115
+ // identically across both transports. The live `pwPage`/`context` stay
116
+ // in-process and never cross the seam (ADR-0003).
117
+ const handContext = { pwPage, context, ensureOpen };
118
+ const { page, dispose: disposeHands } = composeWithHands(handContext, extraHands);
138
119
  return {
139
120
  page,
140
121
  async close() {
141
- if (closed)
122
+ if (closed) {
142
123
  return;
143
- closed = true;
144
- // Detach from the user's browser; do NOT terminate it.
124
+ }
125
+ // Dispose the hands first (their in-process resources), THEN detach from
126
+ // the user's browser without terminating it. browser.close() fires
127
+ // 'disconnected', which runs markClosed.
128
+ await disposeHands();
145
129
  await browser.close();
130
+ markClosed();
131
+ },
132
+ waitForClose() {
133
+ return closedSignal;
146
134
  },
147
- };
148
- }
149
- /** Map a Playwright cookie to the transport-neutral seam {@link Cookie}. */
150
- function toSeamCookie(c) {
151
- return {
152
- name: c.name,
153
- value: c.value,
154
- domain: c.domain,
155
- path: c.path,
156
- expires: c.expires,
157
- httpOnly: c.httpOnly,
158
- secure: c.secure,
159
- sameSite: c.sameSite,
160
- };
161
- }
162
- /** Map a seam {@link Cookie} to a Playwright cookie shape. */
163
- function fromSeamCookie(c) {
164
- return {
165
- name: c.name,
166
- value: c.value,
167
- domain: c.domain,
168
- path: c.path,
169
- expires: c.expires,
170
- httpOnly: c.httpOnly,
171
- secure: c.secure,
172
- sameSite: c.sameSite,
173
135
  };
174
136
  }
175
137
  //# sourceMappingURL=playwright-attach-transport.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"playwright-attach-transport.js","sourceRoot":"","sources":["../src/playwright-attach-transport.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"playwright-attach-transport.js","sourceRoot":"","sources":["../src/playwright-attach-transport.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,68 @@
1
- import { type Page as PwPage } from 'playwright';
1
+ import { chromium } from 'playwright';
2
+ import { type Hand } from './hand-host.js';
2
3
  import { type ProfileLocationOptions } from './profile-location.js';
3
- import type { OpenTarget, Session, Transport, WaitCondition } from './seam.js';
4
+ import type { OpenTarget, Session, Transport } from './seam.js';
5
+ /**
6
+ * The subset of Playwright's `chromium` browser type the launch transport uses.
7
+ *
8
+ * Patchright is an API-compatible Playwright fork, so its `chromium` has the
9
+ * SAME shape (ADR-0003 stays intact: this structural type, like Playwright's
10
+ * own types, is confined to this module and never crosses the seam). We type the
11
+ * lazily-imported stealth chromium against THIS rather than importing any
12
+ * Patchright type, so the dependency stays optional at the type level too.
13
+ */
14
+ type ChromiumLauncher = Pick<typeof chromium, 'launchPersistentContext'>;
15
+ /** The shape `await import('patchright')` is expected to expose. */
16
+ interface StealthModule {
17
+ readonly chromium: ChromiumLauncher;
18
+ }
19
+ /**
20
+ * How the transport obtains the stealth (`patchright`) chromium. This is an
21
+ * INTERNAL test seam, not a public API: tests inject a fake module (or a
22
+ * rejecting importer) here so no real browser/Patchright is needed, exactly as
23
+ * production uses the default lazy `import('patchright')`. It is deliberately
24
+ * NOT on {@link OpenTarget} (ADR-0003: the seam stays free of Playwright/CDP/
25
+ * Patchright concerns).
26
+ */
27
+ export type StealthChromiumImporter = () => Promise<StealthModule>;
28
+ /**
29
+ * Construction-time policy for {@link PlaywrightLaunchTransport}.
30
+ *
31
+ * Stealth is a TRANSPORT-CONSTRUCTION policy (which browser engine + launch
32
+ * flags to use), not a per-open target detail, so it lives here and NOT on
33
+ * {@link OpenTarget} (which stays Playwright/CDP-free per ADR-0003).
34
+ */
35
+ export interface PlaywrightLaunchTransportOptions {
36
+ /**
37
+ * Opt-in Patchright-backed stealth launch. Default `false` (vanilla
38
+ * Playwright). When `true`, the transport launches via the lazily-imported
39
+ * optional `patchright` package, which patches the CDP `Runtime.enable`
40
+ * automation tell that anti-bot WAFs detect (ADR-0002 keeps this as one extra
41
+ * layer, not a replacement for a real profile/IP). If `patchright` is not
42
+ * installed it throws {@link MissingStealthDependencyError}; it NEVER silently
43
+ * falls back to vanilla.
44
+ */
45
+ readonly stealth?: boolean;
46
+ /**
47
+ * Drive a browser ALREADY INSTALLED ON THE SYSTEM instead of the bundled
48
+ * Chromium, named by its install identity (e.g. `'chrome'` to drive the system
49
+ * Google Chrome, Patchright's recommended setup; also `'msedge'`,
50
+ * `'chrome-beta'`, ...). Applies to BOTH stealth and vanilla launches when set.
51
+ * When omitted, Playwright/Patchright's bundled Chromium is used.
52
+ *
53
+ * Maps to Playwright's `channel` launch option internally; we name it
54
+ * `systemBrowser` so the public surface speaks domain language ("use a browser
55
+ * I already have installed") rather than the Playwright term (ADR-0003 keeps
56
+ * Playwright vocabulary out of the public surface).
57
+ */
58
+ readonly systemBrowser?: string;
59
+ /**
60
+ * INTERNAL test seam: override how the stealth chromium is imported. Omit in
61
+ * production (defaults to `import('patchright')`). See
62
+ * {@link StealthChromiumImporter}.
63
+ */
64
+ readonly importStealthChromium?: StealthChromiumImporter;
65
+ }
4
66
  /**
5
67
  * The v1 concrete transport: a Playwright browser the controller LAUNCHES
6
68
  * against a dedicated, persistent profile directory it owns (PRD "Solution,
@@ -17,6 +79,13 @@ import type { OpenTarget, Session, Transport, WaitCondition } from './seam.js';
17
79
  * `WEBHANDS_HOME` env var, or `~/.webhands`). See
18
80
  * {@link resolveProfileLocation}. Because that is a SHARED location, tests pass
19
81
  * a temp `root` (or set the env var) and assert the real home is untouched.
82
+ *
83
+ * STEALTH (opt-in, default OFF): the third constructor arg can enable a
84
+ * Patchright-backed launch ({@link PlaywrightLaunchTransportOptions}). Patchright
85
+ * is an OPTIONAL dependency imported lazily only when stealth is enabled; if it
86
+ * is absent the transport throws {@link MissingStealthDependencyError} rather
87
+ * than falling back to vanilla. This addresses ONLY the CDP `Runtime.enable`
88
+ * automation tell; a real profile/IP/session reputation still matter (ADR-0002).
20
89
  */
21
90
  export declare class PlaywrightLaunchTransport implements Transport {
22
91
  #private;
@@ -24,67 +93,17 @@ export declare class PlaywrightLaunchTransport implements Transport {
24
93
  * @param location overrides for where profiles live (a `root` dir and/or an
25
94
  * `env`). Omit in production to use `~/.webhands`; pass a temp
26
95
  * `root` in tests to isolate the shared profile location.
96
+ * @param hands explicitly-loaded third-party hands to compose alongside the
97
+ * built-ins (Phase 2, ADR-0007). These come from {@link loadHands} against
98
+ * the operator's explicit config; the transport does NOT discover them. Omit
99
+ * for the built-ins-only surface.
100
+ * @param options transport-construction policy, notably the opt-in `stealth`
101
+ * toggle and optional `systemBrowser` (see
102
+ * {@link PlaywrightLaunchTransportOptions}). Defaults to vanilla Playwright,
103
+ * bundled Chromium, stealth OFF.
27
104
  */
28
- constructor(location?: ProfileLocationOptions);
105
+ constructor(location?: ProfileLocationOptions, hands?: readonly Hand[], options?: PlaywrightLaunchTransportOptions);
29
106
  open(target: OpenTarget): Promise<Session>;
30
107
  }
31
- /**
32
- * Run the `wait` verb's three forms (PRD story 10) against a Playwright page.
33
- *
34
- * - `timeout` — pace by a fixed delay (`waitForTimeout`), so an agent can act
35
- * like a human and let XHR-rendered content land.
36
- * - `locator` — block until the addressed element appears (`Locator.waitFor()`),
37
- * the form for content rendered AFTER `goto` settled on `load`.
38
- * - `navigation` — block until the NEXT navigation settles to `load`. We use
39
- * `waitForNavigation()` even though Playwright marks it `@deprecated` ("racy,
40
- * use waitForURL"): that deprecation targets in-process TEST code that can arm
41
- * the wait BEFORE the action and pass a target URL. Neither holds here. Across
42
- * this seam verbs are DISCRETE sequential calls (`click` then `wait`), so we
43
- * CANNOT arm before the trigger; and the realistic trigger is an async,
44
- * JS-driven transition (a redirect / SPA route change that fires AFTER the
45
- * agent's action, the "let XHR-rendered content load" case of story 10), so
46
- * "wait for the NEXT navigation" is exactly right — whereas `waitForLoadState`
47
- * would see the already-loaded current page and return before the pending
48
- * transition. `waitForURL` is unusable because the verb has no target URL by
49
- * design (the agent waits for "a navigation", not a known address). (See the
50
- * task's ## Decisions note.)
51
- *
52
- * Shared by both Playwright transports so the verb behaviour stays identical
53
- * (the forward-note's "do NOT write a parallel second implementation").
54
- */
55
- export declare function waitFor(page: PwPage, condition: WaitCondition): Promise<void>;
56
- /**
57
- * Resolve a raw Playwright locator EXPRESSION (ADR-0004) against the page. The
58
- * verb surface passes locator expressions like `getByRole('button', …)`; we
59
- * evaluate them in a small sandbox where `page`/`p` is the page, so the full
60
- * Playwright locator grammar is available without leaking the type across the
61
- * seam.
62
- *
63
- * Exported (with {@link clickLocator}/{@link waitFor}) so the attach transport
64
- * resolves locators IDENTICALLY — one resolution path, no parallel addressing
65
- * scheme (the forward-note's "do NOT write a parallel second implementation").
66
- */
67
- export declare function resolveLocator(page: PwPage, expression: string): import("playwright").Locator;
68
- /**
69
- * Run the `click` verb against a Playwright page (PRD story 8), shared by both
70
- * Playwright transports so the verb behaves identically (mirrors {@link waitFor};
71
- * the forward-note's "do NOT write a parallel second implementation").
72
- *
73
- * First try a normal `Locator.click()`, which AUTO-WAITS for the element to be
74
- * visible and actionable — the right behaviour for a real button. A hidden
75
- * custom input (the case the prd calls out) NEVER becomes actionable, so that
76
- * click times out; on a Playwright `TimeoutError` we fall back to
77
- * `dispatchEvent('click')`, which fires a click WITHOUT the actionability
78
- * checks. The fallback is deliberately the documented Playwright escape (a
79
- * sibling to the `eval` hatch, ADR-0004), not a reimplemented click: we keep
80
- * the locator a raw resolved expression and only change HOW the resolved
81
- * locator is clicked.
82
- *
83
- * Only a timeout triggers the fallback. The fallback `dispatchEvent` is itself
84
- * bounded by the same short timeout, so a locator that resolves NO element (a
85
- * bad locator) surfaces its timeout quickly instead of hanging the dispatch on
86
- * Playwright's 30s default — the dispatch escape is for elements that EXIST but
87
- * are not actionable (hidden custom inputs), not for absent ones.
88
- */
89
- export declare function clickLocator(page: PwPage, expression: string): Promise<void>;
108
+ export {};
90
109
  //# sourceMappingURL=playwright-launch-transport.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"playwright-launch-transport.d.ts","sourceRoot":"","sources":["../src/playwright-launch-transport.ts"],"names":[],"mappings":"AACA,OAAO,EAIN,KAAK,IAAI,IAAI,MAAM,EACnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAEN,KAAK,sBAAsB,EAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAEX,UAAU,EAEV,OAAO,EAGP,SAAS,EACT,aAAa,EACb,MAAM,WAAW,CAAC;AAEnB;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,yBAA0B,YAAW,SAAS;;IAG1D;;;;OAIG;gBACS,QAAQ,GAAE,sBAA2B;IAI3C,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC;CAwChD;AA2HD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,OAAO,CAC5B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,aAAa,GACtB,OAAO,CAAC,IAAI,CAAC,CAaf;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,gCAO9D;AAcD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,YAAY,CACjC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAYf"}
1
+ {"version":3,"file":"playwright-launch-transport.d.ts","sourceRoot":"","sources":["../src/playwright-launch-transport.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,QAAQ,EAAiC,MAAM,YAAY,CAAC;AAMpE,OAAO,EAAmB,KAAK,IAAI,EAAmB,MAAM,gBAAgB,CAAC;AAC7E,OAAO,EAEN,KAAK,sBAAsB,EAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAC,UAAU,EAAE,OAAO,EAAE,SAAS,EAAC,MAAM,WAAW,CAAC;AAE9D;;;;;;;;GAQG;AACH,KAAK,gBAAgB,GAAG,IAAI,CAAC,OAAO,QAAQ,EAAE,yBAAyB,CAAC,CAAC;AAEzE,oEAAoE;AACpE,UAAU,aAAa;IACtB,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;CACpC;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,uBAAuB,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;AAEnE;;;;;;GAMG;AACH,MAAM,WAAW,gCAAgC;IAChD;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC;;;;OAIG;IACH,QAAQ,CAAC,qBAAqB,CAAC,EAAE,uBAAuB,CAAC;CACzD;AAmBD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,yBAA0B,YAAW,SAAS;;IAO1D;;;;;;;;;;;;OAYG;gBAEF,QAAQ,GAAE,sBAA2B,EACrC,KAAK,GAAE,SAAS,IAAI,EAAO,EAC3B,OAAO,GAAE,gCAAqC;IAUzC,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC;CA8FhD"}