@rester159/blacktip 0.1.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 (63) hide show
  1. package/AGENTS.md +249 -0
  2. package/LICENSE +38 -0
  3. package/README.md +234 -0
  4. package/dist/behavioral/calibration.d.ts +145 -0
  5. package/dist/behavioral/calibration.d.ts.map +1 -0
  6. package/dist/behavioral/calibration.js +242 -0
  7. package/dist/behavioral/calibration.js.map +1 -0
  8. package/dist/behavioral-engine.d.ts +156 -0
  9. package/dist/behavioral-engine.d.ts.map +1 -0
  10. package/dist/behavioral-engine.js +521 -0
  11. package/dist/behavioral-engine.js.map +1 -0
  12. package/dist/blacktip.d.ts +289 -0
  13. package/dist/blacktip.d.ts.map +1 -0
  14. package/dist/blacktip.js +1574 -0
  15. package/dist/blacktip.js.map +1 -0
  16. package/dist/browser-core.d.ts +47 -0
  17. package/dist/browser-core.d.ts.map +1 -0
  18. package/dist/browser-core.js +375 -0
  19. package/dist/browser-core.js.map +1 -0
  20. package/dist/cli.d.ts +20 -0
  21. package/dist/cli.d.ts.map +1 -0
  22. package/dist/cli.js +226 -0
  23. package/dist/cli.js.map +1 -0
  24. package/dist/element-finder.d.ts +42 -0
  25. package/dist/element-finder.d.ts.map +1 -0
  26. package/dist/element-finder.js +240 -0
  27. package/dist/element-finder.js.map +1 -0
  28. package/dist/evasion.d.ts +39 -0
  29. package/dist/evasion.d.ts.map +1 -0
  30. package/dist/evasion.js +488 -0
  31. package/dist/evasion.js.map +1 -0
  32. package/dist/fingerprint.d.ts +19 -0
  33. package/dist/fingerprint.d.ts.map +1 -0
  34. package/dist/fingerprint.js +171 -0
  35. package/dist/fingerprint.js.map +1 -0
  36. package/dist/index.d.ts +19 -0
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/index.js +14 -0
  39. package/dist/index.js.map +1 -0
  40. package/dist/logging.d.ts +13 -0
  41. package/dist/logging.d.ts.map +1 -0
  42. package/dist/logging.js +42 -0
  43. package/dist/logging.js.map +1 -0
  44. package/dist/observability.d.ts +69 -0
  45. package/dist/observability.d.ts.map +1 -0
  46. package/dist/observability.js +189 -0
  47. package/dist/observability.js.map +1 -0
  48. package/dist/proxy-pool.d.ts +101 -0
  49. package/dist/proxy-pool.d.ts.map +1 -0
  50. package/dist/proxy-pool.js +156 -0
  51. package/dist/proxy-pool.js.map +1 -0
  52. package/dist/snapshot.d.ts +59 -0
  53. package/dist/snapshot.d.ts.map +1 -0
  54. package/dist/snapshot.js +91 -0
  55. package/dist/snapshot.js.map +1 -0
  56. package/dist/types.d.ts +243 -0
  57. package/dist/types.d.ts.map +1 -0
  58. package/dist/types.js +15 -0
  59. package/dist/types.js.map +1 -0
  60. package/examples/01-basic-navigate.ts +40 -0
  61. package/examples/02-login-with-mfa.ts +68 -0
  62. package/examples/03-agent-serve-mode.md +98 -0
  63. package/package.json +62 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy-pool.js","sourceRoot":"","sources":["../src/proxy-pool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAmBH;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,UAAU,EAAE,CAAC,QAAgB,EAAE,QAAgB,EAAE,IAAY,EAAmB,EAAE,CAAC,CAAC;QAClF,EAAE,EAAE,cAAc,IAAI,EAAE;QACxB,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAE,mBAAmB;QACzB,IAAI,EAAE,KAAK;QACX,QAAQ,EAAE,gBAAgB,QAAQ,SAAS,IAAI,EAAE;QACjD,QAAQ;QACR,IAAI,EAAE,CAAC,aAAa,EAAE,YAAY,CAAC;KACpC,CAAC;IACF,OAAO,EAAE,CAAC,QAAgB,EAAE,QAAgB,EAAmB,EAAE,CAAC,CAAC;QACjE,EAAE,EAAE,SAAS;QACb,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAE,eAAe;QACrB,IAAI,EAAE,IAAI;QACV,QAAQ;QACR,QAAQ;QACR,IAAI,EAAE,CAAC,aAAa,EAAE,SAAS,CAAC;KACjC,CAAC;IACF,UAAU,EAAE,CAAC,QAAgB,EAAE,QAAgB,EAAmB,EAAE,CAAC,CAAC;QACpE,EAAE,EAAE,YAAY;QAChB,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAE,qBAAqB;QAC3B,IAAI,EAAE,KAAK;QACX,QAAQ;QACR,QAAQ;QACR,IAAI,EAAE,CAAC,aAAa,EAAE,YAAY,CAAC;KACpC,CAAC;IACF,MAAM,EAAE,CAAC,UAA2B,EAAmB,EAAE,CAAC,UAAU;CAC5D,CAAC;AAEX;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,CAAkB;IAC3C,MAAM,IAAI,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,kBAAkB,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACpH,OAAO,GAAG,CAAC,CAAC,QAAQ,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;AACtD,CAAC;AAmBD,MAAM,OAAO,SAAS;IACZ,OAAO,GAAsB,EAAE,CAAC;IAChC,IAAI,GAAgB,EAAE,CAAC;IACvB,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;IACvC,iBAAiB,GAAG,IAAI,GAAG,EAAkB,CAAC;IACrC,UAAU,CAAS;IACnB,QAAQ,CAAuC;IAEhE,YAAY,UAA6B,EAAE,EAAE,UAAuB,EAAE;QACpE,IAAI,CAAC,OAAO,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;QAC5B,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;QAC5D,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,aAAa,CAAC;IACpD,CAAC;IAED,GAAG,CAAC,KAAsB;QACxB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;YACjD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,MAAM,CAAC,OAAe;QACpB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;IAC9D,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED;;;OAGG;IACH,eAAe,CAAC,MAAc;QAC5B,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAE3C,iEAAiE;QACjE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,IAAI,GAAG,CACpB,IAAI,CAAC,IAAI;aACN,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC;aACxE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CACzB,CAAC;QACF,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC/D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAEvC,IAAI,MAAuB,CAAC;QAC5B,QAAQ,IAAI,CAAC,QAAQ,EAAE,CAAC;YACtB,KAAK,QAAQ;gBACX,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAE,CAAC;gBAChE,MAAM;YACR,KAAK,YAAY;gBACf,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CACnC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAClF,CAAC;gBACF,MAAM;YACR,KAAK,aAAa,CAAC;YACnB,OAAO,CAAC,CAAC,CAAC;gBACR,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;gBACzD,MAAM,OAAO,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC;gBAChD,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAC5C,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAE,CAAC;gBAC5B,MAAM;YACR,CAAC;QACH,CAAC;QAED,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1E,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;OAGG;IACH,SAAS,CAAC,OAAe,EAAE,MAAc,EAAE,MAAe;QACxD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YACb,OAAO;YACP,MAAM;YACN,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE;YACpB,MAAM;SACP,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,gBAAgB;QACd,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;QACxE,OAAO,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,qBAAqB;QACnB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,OAAO;YACL,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;YAC1B,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC;YACvE,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;SACrD,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Session snapshot/restore.
3
+ *
4
+ * Serializes the cookies, localStorage, sessionStorage, and current URL
5
+ * of a BlackTip session into a JSON blob. `restore` applies the snapshot
6
+ * to a BlackTip instance so you can:
7
+ *
8
+ * - Migrate a logged-in session from one proxy to another.
9
+ * - Promote a known-good session to a new BlackTip instance if the
10
+ * current one crashes.
11
+ * - Park a session overnight and resume tomorrow without re-logging in.
12
+ *
13
+ * NOT yet serialized: IndexedDB contents, Service Worker state, Cache
14
+ * Storage. Those are non-trivial and worth a future addition once a
15
+ * real target needs them (most auth sessions use cookies + localStorage,
16
+ * which is what we cover here).
17
+ */
18
+ import type { BrowserCore } from './browser-core.js';
19
+ export interface SessionSnapshot {
20
+ /** Schema version — bump on incompatible changes. */
21
+ version: 1;
22
+ /** Timestamp of when the snapshot was taken. */
23
+ capturedAt: string;
24
+ /** The URL the active page was on at capture time. */
25
+ url: string;
26
+ /** Browser cookies as a flat array of {name, value, domain, path, ...}. */
27
+ cookies: Array<{
28
+ name: string;
29
+ value: string;
30
+ domain: string;
31
+ path: string;
32
+ expires?: number;
33
+ httpOnly?: boolean;
34
+ secure?: boolean;
35
+ sameSite?: 'Lax' | 'None' | 'Strict';
36
+ }>;
37
+ /** localStorage keyed by origin. */
38
+ localStorageByOrigin: Record<string, Record<string, string>>;
39
+ /** sessionStorage keyed by origin. */
40
+ sessionStorageByOrigin: Record<string, Record<string, string>>;
41
+ /** Optional user label. */
42
+ label?: string;
43
+ }
44
+ export declare class SnapshotManager {
45
+ private core;
46
+ constructor(core: BrowserCore);
47
+ /**
48
+ * Capture the current session state. Reads cookies from the browser
49
+ * context and storage from the active page via evaluate.
50
+ */
51
+ capture(label?: string): Promise<SessionSnapshot>;
52
+ /**
53
+ * Apply a snapshot to the current BlackTip session. Sets cookies,
54
+ * navigates to the captured URL, then writes localStorage and
55
+ * sessionStorage for the origin.
56
+ */
57
+ restore(snapshot: SessionSnapshot): Promise<void>;
58
+ }
59
+ //# sourceMappingURL=snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,WAAW,eAAe;IAC9B,qDAAqD;IACrD,OAAO,EAAE,CAAC,CAAC;IACX,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,GAAG,EAAE,MAAM,CAAC;IACZ,2EAA2E;IAC3E,OAAO,EAAE,KAAK,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,QAAQ,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAC;KACtC,CAAC,CAAC;IACH,oCAAoC;IACpC,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7D,sCAAsC;IACtC,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC/D,2BAA2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,eAAe;IACd,OAAO,CAAC,IAAI;gBAAJ,IAAI,EAAE,WAAW;IAErC;;;OAGG;IACG,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAsCvD;;;;OAIG;IACG,OAAO,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;CA4BxD"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Session snapshot/restore.
3
+ *
4
+ * Serializes the cookies, localStorage, sessionStorage, and current URL
5
+ * of a BlackTip session into a JSON blob. `restore` applies the snapshot
6
+ * to a BlackTip instance so you can:
7
+ *
8
+ * - Migrate a logged-in session from one proxy to another.
9
+ * - Promote a known-good session to a new BlackTip instance if the
10
+ * current one crashes.
11
+ * - Park a session overnight and resume tomorrow without re-logging in.
12
+ *
13
+ * NOT yet serialized: IndexedDB contents, Service Worker state, Cache
14
+ * Storage. Those are non-trivial and worth a future addition once a
15
+ * real target needs them (most auth sessions use cookies + localStorage,
16
+ * which is what we cover here).
17
+ */
18
+ export class SnapshotManager {
19
+ core;
20
+ constructor(core) {
21
+ this.core = core;
22
+ }
23
+ /**
24
+ * Capture the current session state. Reads cookies from the browser
25
+ * context and storage from the active page via evaluate.
26
+ */
27
+ async capture(label) {
28
+ const page = this.core.getActivePage();
29
+ const url = page.url();
30
+ const cookies = await this.core.cookies();
31
+ // Storage must be read in-page. sessionStorage is per-origin and only
32
+ // reachable when we're on that origin. For multi-origin sessions the
33
+ // caller would need to navigate to each origin and call capture
34
+ // incrementally — this single-shot version covers the active origin.
35
+ const storageRaw = (await this.core.executeJS(`(() => {
36
+ const originKey = location.origin;
37
+ const readStorage = (store) => {
38
+ const out = {};
39
+ for (let i = 0; i < store.length; i++) {
40
+ const k = store.key(i);
41
+ if (k != null) out[k] = store.getItem(k) ?? '';
42
+ }
43
+ return out;
44
+ };
45
+ return {
46
+ origin: originKey,
47
+ local: readStorage(localStorage),
48
+ session: readStorage(sessionStorage),
49
+ };
50
+ })()`));
51
+ return {
52
+ version: 1,
53
+ capturedAt: new Date().toISOString(),
54
+ url,
55
+ cookies: cookies,
56
+ localStorageByOrigin: { [storageRaw.origin]: storageRaw.local },
57
+ sessionStorageByOrigin: { [storageRaw.origin]: storageRaw.session },
58
+ label,
59
+ };
60
+ }
61
+ /**
62
+ * Apply a snapshot to the current BlackTip session. Sets cookies,
63
+ * navigates to the captured URL, then writes localStorage and
64
+ * sessionStorage for the origin.
65
+ */
66
+ async restore(snapshot) {
67
+ if (snapshot.version !== 1) {
68
+ throw new Error(`Unsupported snapshot version: ${snapshot.version}`);
69
+ }
70
+ // Cookies first — they need to be in place before navigation so the
71
+ // page request carries them.
72
+ if (snapshot.cookies.length > 0) {
73
+ await this.core.setCookies(snapshot.cookies);
74
+ }
75
+ // Navigate to the captured URL.
76
+ if (snapshot.url) {
77
+ await this.core.navigate(snapshot.url, { waitUntil: 'domcontentloaded' });
78
+ }
79
+ // Write storage for each origin. The active page is now on one
80
+ // origin; we can only write to that origin's storage from here.
81
+ const page = this.core.getActivePage();
82
+ const currentOrigin = new URL(page.url()).origin;
83
+ const local = snapshot.localStorageByOrigin[currentOrigin] ?? {};
84
+ const session = snapshot.sessionStorageByOrigin[currentOrigin] ?? {};
85
+ await this.core.executeJS(`((localKv, sessionKv) => {
86
+ for (const [k, v] of Object.entries(localKv)) localStorage.setItem(k, v);
87
+ for (const [k, v] of Object.entries(sessionKv)) sessionStorage.setItem(k, v);
88
+ })(${JSON.stringify(local)}, ${JSON.stringify(session)})`);
89
+ }
90
+ }
91
+ //# sourceMappingURL=snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AA8BH,MAAM,OAAO,eAAe;IACN;IAApB,YAAoB,IAAiB;QAAjB,SAAI,GAAJ,IAAI,CAAa;IAAG,CAAC;IAEzC;;;OAGG;IACH,KAAK,CAAC,OAAO,CAAC,KAAc;QAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEvB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAE1C,sEAAsE;QACtE,qEAAqE;QACrE,gEAAgE;QAChE,qEAAqE;QACrE,MAAM,UAAU,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;;;;;;;;;;;;;;;SAezC,CAAC,CAAuF,CAAC;QAE9F,OAAO;YACL,OAAO,EAAE,CAAC;YACV,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACpC,GAAG;YACH,OAAO,EAAE,OAAqC;YAC9C,oBAAoB,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,KAAK,EAAE;YAC/D,sBAAsB,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,OAAO,EAAE;YACnE,KAAK;SACN,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,OAAO,CAAC,QAAyB;QACrC,IAAI,QAAQ,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,iCAAiC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;QACvE,CAAC;QAED,oEAAoE;QACpE,6BAA6B;QAC7B,IAAI,QAAQ,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC/C,CAAC;QAED,gCAAgC;QAChC,IAAI,QAAQ,CAAC,GAAG,EAAE,CAAC;YACjB,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAC5E,CAAC;QAED,+DAA+D;QAC/D,gEAAgE;QAChE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;QACvC,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC;QACjD,MAAM,KAAK,GAAG,QAAQ,CAAC,oBAAoB,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;QACjE,MAAM,OAAO,GAAG,QAAQ,CAAC,sBAAsB,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;QAErE,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;;;SAGrB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC7D,CAAC;CACF"}
@@ -0,0 +1,243 @@
1
+ export interface BlackTipConfig {
2
+ behaviorProfile?: string | ProfileConfig;
3
+ logLevel?: LogLevel;
4
+ timeout?: number;
5
+ retryAttempts?: number;
6
+ headless?: boolean;
7
+ proxy?: string;
8
+ deviceProfile?: string;
9
+ locale?: string;
10
+ timezone?: string;
11
+ screenResolution?: {
12
+ width: number;
13
+ height: number;
14
+ };
15
+ persistent?: boolean;
16
+ chromiumPath?: string;
17
+ }
18
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
19
+ export interface ProfileConfig {
20
+ typingSpeedMs: [number, number];
21
+ pauseBetweenActionsMs: [number, number];
22
+ scrollSpeedMs: [number, number];
23
+ mouseMovementCurve: 'bezier' | 'linear';
24
+ clickDwellMs: [number, number];
25
+ readingWpm: [number, number];
26
+ mistakeRate: number;
27
+ recoveryBehavior: 'natural' | 'fast';
28
+ pasteThreshold: number;
29
+ }
30
+ export interface DeviceProfile {
31
+ name: string;
32
+ userAgent: string;
33
+ platform: string;
34
+ oscpu?: string;
35
+ hardwareConcurrency: number;
36
+ deviceMemory: number;
37
+ maxTouchPoints: number;
38
+ screenWidth: number;
39
+ screenHeight: number;
40
+ devicePixelRatio: number;
41
+ colorDepth: number;
42
+ vendor: string;
43
+ renderer: string;
44
+ webglVendor: string;
45
+ webglRenderer: string;
46
+ languages: string[];
47
+ plugins: PluginData[];
48
+ fonts: string[];
49
+ }
50
+ export interface PluginData {
51
+ name: string;
52
+ description: string;
53
+ filename: string;
54
+ mimeTypes: {
55
+ type: string;
56
+ suffixes: string;
57
+ description: string;
58
+ }[];
59
+ }
60
+ export interface ActionResult {
61
+ success: boolean;
62
+ duration: number;
63
+ retries: number;
64
+ error?: string;
65
+ errorCode?: string;
66
+ }
67
+ export interface NavigateResult {
68
+ success: boolean;
69
+ url: string;
70
+ status: number;
71
+ duration: number;
72
+ error?: string;
73
+ }
74
+ export interface ScreenshotResult {
75
+ data: Buffer;
76
+ format: 'png' | 'jpeg';
77
+ width: number;
78
+ height: number;
79
+ timestamp: string;
80
+ }
81
+ export interface WaitResult {
82
+ success: boolean;
83
+ duration: number;
84
+ error?: string;
85
+ }
86
+ export interface NavigateOptions {
87
+ waitUntil?: 'load' | 'domcontentloaded' | 'networkidle';
88
+ timeout?: number;
89
+ }
90
+ /**
91
+ * Action importance hint. Drives pre-action hesitation length and
92
+ * behavioral intensity. Pass `'high'` on consequential clicks like
93
+ * submit/pay/confirm buttons so BlackTip hesitates like a real user
94
+ * would before committing.
95
+ */
96
+ export type ActionImportance = 'low' | 'normal' | 'high';
97
+ export interface ClickOptions {
98
+ button?: 'left' | 'right' | 'middle';
99
+ count?: number;
100
+ timeout?: number;
101
+ importance?: ActionImportance;
102
+ }
103
+ export interface TypeOptions {
104
+ clearFirst?: boolean;
105
+ pressEnter?: boolean;
106
+ paste?: boolean;
107
+ timeout?: number;
108
+ importance?: ActionImportance;
109
+ }
110
+ export interface ScrollOptions {
111
+ direction?: 'up' | 'down' | 'left' | 'right';
112
+ amount?: number;
113
+ selector?: string;
114
+ smooth?: boolean;
115
+ }
116
+ export interface HoverOptions {
117
+ timeout?: number;
118
+ }
119
+ export interface SelectOptions {
120
+ timeout?: number;
121
+ }
122
+ export interface PressKeyOptions {
123
+ timeout?: number;
124
+ }
125
+ export interface UploadFileOptions {
126
+ method?: 'auto' | 'input' | 'dragdrop';
127
+ timeout?: number;
128
+ }
129
+ export interface ExtractTextOptions {
130
+ multiple?: boolean;
131
+ }
132
+ export interface WaitForOptions {
133
+ timeout?: number;
134
+ visible?: boolean;
135
+ hidden?: boolean;
136
+ }
137
+ export interface WaitForNavigationOptions {
138
+ waitUntil?: 'load' | 'domcontentloaded' | 'networkidle';
139
+ timeout?: number;
140
+ }
141
+ export interface ScreenshotOptions {
142
+ fullPage?: boolean;
143
+ format?: 'png' | 'jpeg';
144
+ quality?: number;
145
+ path?: string;
146
+ }
147
+ export interface PageContentOptions {
148
+ format?: 'text' | 'html';
149
+ }
150
+ export interface TabInfo {
151
+ index: number;
152
+ url: string;
153
+ title: string;
154
+ active: boolean;
155
+ }
156
+ export interface FrameInfo {
157
+ name: string;
158
+ url: string;
159
+ index: number;
160
+ }
161
+ export interface ActionEvent {
162
+ timestamp: string;
163
+ action: string;
164
+ target: string;
165
+ value?: string;
166
+ outcome: 'success' | 'failure';
167
+ duration: number;
168
+ retries: number;
169
+ behavioral?: BehavioralMetadata;
170
+ error?: string;
171
+ tabIndex?: number;
172
+ }
173
+ export interface BehavioralMetadata {
174
+ mousePathLength?: number;
175
+ mouseMoveDuration?: number;
176
+ clickDwell?: number;
177
+ preActionPause?: number;
178
+ postActionPause?: number;
179
+ typingDuration?: number;
180
+ }
181
+ export interface ErrorEvent {
182
+ timestamp: string;
183
+ code: string;
184
+ message: string;
185
+ url: string;
186
+ action: string;
187
+ attempts: number;
188
+ screenshot?: Buffer;
189
+ stack?: string;
190
+ }
191
+ export interface RetryEvent {
192
+ timestamp: string;
193
+ action: string;
194
+ target: string;
195
+ attempt: number;
196
+ maxAttempts: number;
197
+ strategy: RetryStrategy;
198
+ error: string;
199
+ }
200
+ export type RetryStrategy = 'standard' | 'wait' | 'reload' | 'altSelector' | 'scroll' | 'clearOverlays';
201
+ export interface TabChangeEvent {
202
+ timestamp: string;
203
+ tabIndex: number;
204
+ url: string;
205
+ action: 'opened' | 'closed' | 'switched';
206
+ }
207
+ export interface LogEntry {
208
+ timestamp: string;
209
+ level: LogLevel;
210
+ message: string;
211
+ data?: Record<string, unknown>;
212
+ }
213
+ export declare const ErrorCodes: {
214
+ readonly TIMEOUT: "TIMEOUT";
215
+ readonly ELEMENT_NOT_FOUND: "ELEMENT_NOT_FOUND";
216
+ readonly NAVIGATION_FAILED: "NAVIGATION_FAILED";
217
+ readonly JS_ERROR: "JS_ERROR";
218
+ readonly UPLOAD_FAILED: "UPLOAD_FAILED";
219
+ readonly SESSION_EXPIRED: "SESSION_EXPIRED";
220
+ readonly BROWSER_CRASHED: "BROWSER_CRASHED";
221
+ readonly PROXY_ERROR: "PROXY_ERROR";
222
+ readonly FRAME_NOT_FOUND: "FRAME_NOT_FOUND";
223
+ readonly NOT_LAUNCHED: "NOT_LAUNCHED";
224
+ };
225
+ export type ErrorCode = typeof ErrorCodes[keyof typeof ErrorCodes];
226
+ export interface Point {
227
+ x: number;
228
+ y: number;
229
+ }
230
+ export interface BoundingBox {
231
+ x: number;
232
+ y: number;
233
+ width: number;
234
+ height: number;
235
+ }
236
+ export interface ElementHandle {
237
+ selector: string;
238
+ boundingBox: BoundingBox;
239
+ tagName: string;
240
+ isVisible: boolean;
241
+ frameIndex?: number;
242
+ }
243
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,cAAc;IAC7B,eAAe,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC;IACzC,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAI3D,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,qBAAqB,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,kBAAkB,EAAE,QAAQ,GAAG,QAAQ,CAAC;IACxC,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,SAAS,GAAG,MAAM,CAAC;IACrC,cAAc,EAAE,MAAM,CAAC;CACxB;AAID,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mBAAmB,EAAE,MAAM,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACtE;AAID,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,MAAM,GAAG,kBAAkB,GAAG,aAAa,CAAC;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEzD,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC/B;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC/B;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,CAAC,EAAE,MAAM,GAAG,kBAAkB,GAAG,aAAa,CAAC;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1B;AAID,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAID,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,SAAS,GAAG,SAAS,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,kBAAkB,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,aAAa,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,aAAa,GAAG,QAAQ,GAAG,eAAe,CAAC;AAExG,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC;CAC1C;AAED,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,QAAQ,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAID,eAAO,MAAM,UAAU;;;;;;;;;;;CAWb,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,OAAO,UAAU,CAAC,MAAM,OAAO,UAAU,CAAC,CAAC;AAInE,MAAM,WAAW,KAAK;IACpB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,WAAW;IAC1B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
package/dist/types.js ADDED
@@ -0,0 +1,15 @@
1
+ // ── Configuration ──
2
+ // ── Error Codes ──
3
+ export const ErrorCodes = {
4
+ TIMEOUT: 'TIMEOUT',
5
+ ELEMENT_NOT_FOUND: 'ELEMENT_NOT_FOUND',
6
+ NAVIGATION_FAILED: 'NAVIGATION_FAILED',
7
+ JS_ERROR: 'JS_ERROR',
8
+ UPLOAD_FAILED: 'UPLOAD_FAILED',
9
+ SESSION_EXPIRED: 'SESSION_EXPIRED',
10
+ BROWSER_CRASHED: 'BROWSER_CRASHED',
11
+ PROXY_ERROR: 'PROXY_ERROR',
12
+ FRAME_NOT_FOUND: 'FRAME_NOT_FOUND',
13
+ NOT_LAUNCHED: 'NOT_LAUNCHED',
14
+ };
15
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,sBAAsB;AA2PtB,oBAAoB;AAEpB,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,OAAO,EAAE,SAAS;IAClB,iBAAiB,EAAE,mBAAmB;IACtC,iBAAiB,EAAE,mBAAmB;IACtC,QAAQ,EAAE,UAAU;IACpB,aAAa,EAAE,eAAe;IAC9B,eAAe,EAAE,iBAAiB;IAClC,eAAe,EAAE,iBAAiB;IAClC,WAAW,EAAE,aAAa;IAC1B,eAAe,EAAE,iBAAiB;IAClC,YAAY,EAAE,cAAc;CACpB,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Basic navigation + extraction example.
3
+ *
4
+ * Run with: npx tsx examples/01-basic-navigate.ts
5
+ */
6
+
7
+ import { BlackTip } from '@rester159/blacktip';
8
+
9
+ async function main(): Promise<void> {
10
+ const bt = new BlackTip({
11
+ logLevel: 'info',
12
+ timeout: 10_000,
13
+ retryAttempts: 2,
14
+ });
15
+
16
+ await bt.launch();
17
+
18
+ try {
19
+ // Navigate and wait for the page to settle.
20
+ await bt.navigate('https://en.wikipedia.org/wiki/Playwright_(software)');
21
+ await bt.waitForStable({ networkIdleMs: 500, domIdleMs: 500 });
22
+
23
+ // Extract the article title and first paragraph.
24
+ const title = await bt.extractText('#firstHeading');
25
+ const firstParagraph = await bt.extractText('#mw-content-text .mw-parser-output > p');
26
+
27
+ console.log('Title:', title);
28
+ console.log('First paragraph:', String(firstParagraph).slice(0, 200), '...');
29
+
30
+ // Take a screenshot for the record.
31
+ await bt.screenshot({ path: 'wikipedia-playwright.png' });
32
+ } finally {
33
+ await bt.close();
34
+ }
35
+ }
36
+
37
+ main().catch((e) => {
38
+ console.error(e);
39
+ process.exit(1);
40
+ });
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Login flow with MFA — demonstrates pauseForInput.
3
+ *
4
+ * This runs BlackTip in serve mode, then sends commands from the same
5
+ * file for simplicity. In a real agent setup, the driving logic lives
6
+ * in your agent framework and sends commands over the TCP protocol.
7
+ *
8
+ * Run with: npx tsx examples/02-login-with-mfa.ts
9
+ */
10
+
11
+ import { BlackTip } from '@rester159/blacktip';
12
+ import * as readline from 'node:readline/promises';
13
+
14
+ async function main(): Promise<void> {
15
+ const bt = new BlackTip({
16
+ logLevel: 'info',
17
+ timeout: 15_000,
18
+ retryAttempts: 2,
19
+ behaviorProfile: 'human',
20
+ });
21
+
22
+ await bt.launch();
23
+
24
+ // Listen for pause events and prompt the user via stdin.
25
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
26
+ bt.on('btPause', async (info: { id: string; prompt: string }) => {
27
+ const answer = await rl.question(`\n[BlackTip] ${info.prompt}\n> `);
28
+ // Resume by directly resolving the pending entry.
29
+ const registry = (bt as unknown as { _pauseRegistry?: Map<string, { resolve: (v: string) => void }> })._pauseRegistry;
30
+ registry?.get(info.id)?.resolve(answer);
31
+ registry?.delete(info.id);
32
+ });
33
+
34
+ // Set up the pause registry without going through serve mode.
35
+ (bt as unknown as { _pauseRegistry: Map<string, unknown> })._pauseRegistry = new Map();
36
+
37
+ try {
38
+ await bt.navigate('https://example-site-with-mfa.com/login');
39
+
40
+ await bt.type('input[name="email"]', 'you@example.com', { paste: true });
41
+ await bt.type('input[name="password"]', process.env.DEMO_PASSWORD ?? '', { paste: true });
42
+ await bt.click('button[type="submit"]'); // auto-importance applies
43
+
44
+ await bt.waitForText('Enter verification code', { timeout: 10_000 });
45
+
46
+ // Pause and ask the user for the MFA code. The 'btPause' listener
47
+ // above prompts via readline and resumes.
48
+ const code = await bt.pauseForInput({
49
+ prompt: 'Enter the 6-digit code sent to your phone',
50
+ validate: /^\d{6}$/,
51
+ timeoutMs: 300_000,
52
+ });
53
+
54
+ await bt.type('input[name="code"]', code, { paste: true });
55
+ await bt.click('button[type="submit"]');
56
+
57
+ await bt.waitForStable();
58
+ console.log('Logged in, current URL:', (await bt.screenshot()).timestamp, '/', await bt.executeJS('location.href'));
59
+ } finally {
60
+ rl.close();
61
+ await bt.close();
62
+ }
63
+ }
64
+
65
+ main().catch((e) => {
66
+ console.error(e);
67
+ process.exit(1);
68
+ });
@@ -0,0 +1,98 @@
1
+ # Example 3 — Agent driving BlackTip in serve mode
2
+
3
+ This is the pattern used by the BlackTip design: an LLM agent in one process, a BlackTip server in another, and one-command-at-a-time interaction.
4
+
5
+ ## Start the server
6
+
7
+ ```bash
8
+ npx blacktip serve --port 9779
9
+ ```
10
+
11
+ The server launches a real Chrome window and listens for TCP commands.
12
+
13
+ ## Send commands
14
+
15
+ ```bash
16
+ # Single command with pretty output (screenshot path shown, not raw base64)
17
+ npx blacktip send "await bt.navigate('https://example.com')" --pretty
18
+
19
+ # Command from a file — no shell escaping needed
20
+ echo 'await bt.type("#email", "you@example.com", { paste: true })' > cmd.js
21
+ npx blacktip send --file cmd.js --pretty
22
+
23
+ # Command from stdin
24
+ echo 'return await bt.inspect("#submit-button")' | npx blacktip send --stdin --pretty
25
+
26
+ # Batch: run many commands sequentially, stop on first failure
27
+ cat > flow.json <<'EOF'
28
+ [
29
+ "await bt.navigate('https://example.com/login')",
30
+ "await bt.waitForStable()",
31
+ "await bt.type('#email', 'you@example.com', {paste: true})",
32
+ "await bt.type('#password', 'secret', {paste: true})",
33
+ "await bt.click('#submit')",
34
+ "await bt.waitForText('Welcome')"
35
+ ]
36
+ EOF
37
+ npx blacktip batch flow.json
38
+ ```
39
+
40
+ ## Response format
41
+
42
+ Every `send` returns a JSON bundle:
43
+
44
+ ```json
45
+ {
46
+ "ok": true,
47
+ "result": "... whatever the JS command returned, if anything",
48
+ "url": "https://example.com/",
49
+ "title": "Example Domain",
50
+ "screenshotPath": "shot.png",
51
+ "screenshotB64": "iVBORw0KGgoAAAA...",
52
+ "screenshotBytes": 41234,
53
+ "durationMs": 432
54
+ }
55
+ ```
56
+
57
+ With `--pretty`, the `screenshotB64` field is replaced by a placeholder so the console output is readable. The PNG is still saved to `shot.png` (or whatever `screenshotPath` you configured).
58
+
59
+ ## Handling MFA
60
+
61
+ When a command calls `bt.pauseForInput()`, the server sends a pause frame:
62
+
63
+ ```json
64
+ {"ok": true, "paused": true, "pauseId": "pause-1712345678-12345", "prompt": "Enter the SMS code"}
65
+ ```
66
+
67
+ The `send` command that triggered the pause blocks on the client side until you resume. From a second terminal:
68
+
69
+ ```bash
70
+ npx blacktip resume pause-1712345678-12345 "116170"
71
+ ```
72
+
73
+ The paused command continues executing with the value you provided.
74
+
75
+ ## Listing pending pauses
76
+
77
+ ```bash
78
+ npx blacktip pending
79
+ ```
80
+
81
+ Useful in long-running flows with multiple potential pause points.
82
+
83
+ ## Agent decision loop (pseudocode)
84
+
85
+ ```
86
+ start server
87
+ navigate to target
88
+ loop:
89
+ send one command
90
+ parse the bundle
91
+ look at the screenshot (base64 or on disk)
92
+ decide the next action based on what you see
93
+ if uncertain, ask the user
94
+ if the action is destructive (submit, pay, delete), summarize and confirm first
95
+ send the next command
96
+ ```
97
+
98
+ The crucial rule: **never pre-script a multi-step sequence.** Look, decide, act, repeat. Pages change between steps and pre-scripted flows fail on the first surprise.