supersurf-mcp 3.0.2 → 3.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 (46) hide show
  1. package/dist/experimental/fingerprinting/index.d.ts +57 -0
  2. package/dist/experimental/fingerprinting/index.d.ts.map +1 -0
  3. package/dist/experimental/fingerprinting/index.js +150 -0
  4. package/dist/experimental/fingerprinting/index.js.map +1 -0
  5. package/dist/experimental/fingerprinting/page-scripts.d.ts +7 -0
  6. package/dist/experimental/fingerprinting/page-scripts.d.ts.map +1 -0
  7. package/dist/experimental/fingerprinting/page-scripts.js +67 -0
  8. package/dist/experimental/fingerprinting/page-scripts.js.map +1 -0
  9. package/dist/experimental/fingerprinting/store.d.ts +8 -0
  10. package/dist/experimental/fingerprinting/store.d.ts.map +1 -0
  11. package/dist/experimental/fingerprinting/store.js +78 -0
  12. package/dist/experimental/fingerprinting/store.js.map +1 -0
  13. package/dist/experimental/fingerprinting/types.d.ts +32 -0
  14. package/dist/experimental/fingerprinting/types.d.ts.map +1 -0
  15. package/dist/experimental/fingerprinting/types.js +3 -0
  16. package/dist/experimental/fingerprinting/types.js.map +1 -0
  17. package/dist/experimental/index.js +1 -1
  18. package/dist/experimental/index.js.map +1 -1
  19. package/dist/recorder/action-recorder.d.ts +25 -0
  20. package/dist/recorder/action-recorder.d.ts.map +1 -0
  21. package/dist/recorder/action-recorder.js +48 -0
  22. package/dist/recorder/action-recorder.js.map +1 -0
  23. package/dist/shared/config/defaults.d.ts.map +1 -1
  24. package/dist/shared/config/defaults.js +3 -1
  25. package/dist/shared/config/defaults.js.map +1 -1
  26. package/dist/shared/config/loaders.d.ts.map +1 -1
  27. package/dist/shared/config/loaders.js +1 -4
  28. package/dist/shared/config/loaders.js.map +1 -1
  29. package/dist/shared/config/service.d.ts.map +1 -1
  30. package/dist/shared/config/service.js +2 -0
  31. package/dist/shared/config/service.js.map +1 -1
  32. package/dist/shared/config/types.d.ts +2 -0
  33. package/dist/shared/config/types.d.ts.map +1 -1
  34. package/dist/tools/interaction/registry.d.ts.map +1 -1
  35. package/dist/tools/interaction/registry.js +11 -1
  36. package/dist/tools/interaction/registry.js.map +1 -1
  37. package/dist/tools/lib/frames.d.ts +13 -8
  38. package/dist/tools/lib/frames.d.ts.map +1 -1
  39. package/dist/tools/lib/frames.js +164 -80
  40. package/dist/tools/lib/frames.js.map +1 -1
  41. package/dist/tools/lib/types.d.ts +21 -0
  42. package/dist/tools/lib/types.d.ts.map +1 -1
  43. package/dist/tools.d.ts.map +1 -1
  44. package/dist/tools.js +29 -1
  45. package/dist/tools.js.map +1 -1
  46. package/package.json +1 -1
@@ -0,0 +1,57 @@
1
+ import type { EvalFn } from '../../tools/lib/element-resolver';
2
+ import type { ScoreHit } from './types';
3
+ export declare const THRESHOLD = 0.6;
4
+ export declare const MARGIN = 0.1;
5
+ export declare function domainOf(url: string | undefined): string;
6
+ export declare function routeOf(url: string | undefined): string;
7
+ export declare function passesGate(hit: ScoreHit): boolean;
8
+ /** Fire-and-forget: fingerprint the just-resolved element and persist it. Never throws. */
9
+ export declare function captureOnResolve(evalFn: EvalFn, url: string | undefined, selector: string): Promise<void>;
10
+ /**
11
+ * Capture an element resolved inside a child frame (iframe). The top-frame capture path
12
+ * (`resolveWithHealing`) can't see iframe elements because it evals against the top frame,
13
+ * so `getCenterInFrame`'s frame-walk fallback calls this with an `evalFn` already bound to
14
+ * the child frame's execution context. Gated + fire-and-forget; never throws.
15
+ */
16
+ export declare function captureInContext(evalInContext: EvalFn, url: string | undefined, selector: string): Promise<void>;
17
+ /** Outcome of a heal attempt, with enough detail for telemetry on every branch. */
18
+ export interface HealAttempt {
19
+ hadRecord: boolean;
20
+ score: number | null;
21
+ margin: number | null;
22
+ hit: ScoreHit | null;
23
+ }
24
+ /** On a selector miss, try to heal via stored fingerprint. Returns the attempt detail; `hit` is set only when the gate passes. */
25
+ export declare function healOnMiss(evalFn: EvalFn, url: string | undefined, selector: string): Promise<HealAttempt>;
26
+ /**
27
+ * Heal a selector miss inside a child frame (iframe). The top-frame heal path
28
+ * (`resolveWithHealing`) evals against the top frame, so it can't see iframe
29
+ * elements; `getCenterInFrame`'s frame-walk fallback calls this with an `evalFn`
30
+ * already bound to a child frame's execution context. Returns the gate-passing
31
+ * hit's **iframe-local** center + score/margin (the caller translates to
32
+ * top-frame coords), or null when there's no record / the gate fails. Gated;
33
+ * never throws.
34
+ */
35
+ export declare function healInContext(evalInContext: EvalFn, url: string | undefined, selector: string): Promise<ScoreHit | null>;
36
+ /** Telemetry event emitted per resolve when the experiment is on (written to the usage-metrics trail). */
37
+ export interface HealEvent {
38
+ event: 'fingerprint';
39
+ outcome: 'resolved' | 'healed' | 'escalated';
40
+ selector: string;
41
+ domain: string;
42
+ route: string;
43
+ score: number | null;
44
+ margin: number | null;
45
+ hadRecord: boolean;
46
+ }
47
+ export type HealEmit = (ev: HealEvent) => void;
48
+ /**
49
+ * Drop-in wrapper for getElementCenter. When the experiment is OFF, behaves identically
50
+ * to getElementCenter. When ON: captures on success, heals on miss, escalates (rethrows)
51
+ * if healing fails.
52
+ */
53
+ export declare function resolveWithHealing(evalFn: EvalFn, selector: string, getUrl: () => string | undefined, emit?: HealEmit): Promise<{
54
+ x: number;
55
+ y: number;
56
+ }>;
57
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/experimental/fingerprinting/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kCAAkC,CAAC;AAK/D,OAAO,KAAK,EAAkC,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExE,eAAO,MAAM,SAAS,MAAM,CAAC;AAC7B,eAAO,MAAM,MAAM,MAAO,CAAC;AAE3B,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAExD;AACD,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAEvD;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAEjD;AAOD,2FAA2F;AAC3F,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkB/G;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGtH;AAED,mFAAmF;AACnF,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,GAAG,EAAE,QAAQ,GAAG,IAAI,CAAC;CACtB;AAED,kIAAkI;AAClI,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAOhH;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAQ9H;AAED,0GAA0G;AAC1G,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,aAAa,CAAC;IACrB,OAAO,EAAE,UAAU,GAAG,QAAQ,GAAG,WAAW,CAAC;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;CACpB;AACD,MAAM,MAAM,QAAQ,GAAG,CAAC,EAAE,EAAE,SAAS,KAAK,IAAI,CAAC;AAE/C;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,MAAM,GAAG,SAAS,EAChC,IAAI,CAAC,EAAE,QAAQ,GACd,OAAO,CAAC;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA4BnC"}
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MARGIN = exports.THRESHOLD = void 0;
4
+ exports.domainOf = domainOf;
5
+ exports.routeOf = routeOf;
6
+ exports.passesGate = passesGate;
7
+ exports.captureOnResolve = captureOnResolve;
8
+ exports.captureInContext = captureInContext;
9
+ exports.healOnMiss = healOnMiss;
10
+ exports.healInContext = healInContext;
11
+ exports.resolveWithHealing = resolveWithHealing;
12
+ const element_resolver_1 = require("../../tools/lib/element-resolver");
13
+ const index_1 = require("../index");
14
+ const store_1 = require("./store");
15
+ const page_scripts_1 = require("./page-scripts");
16
+ exports.THRESHOLD = 0.6;
17
+ exports.MARGIN = 0.10;
18
+ function domainOf(url) {
19
+ try {
20
+ return new URL(url || '').hostname.replace(/^www\./, '') || 'unknown';
21
+ }
22
+ catch {
23
+ return 'unknown';
24
+ }
25
+ }
26
+ function routeOf(url) {
27
+ try {
28
+ return new URL(url || '').pathname || '/';
29
+ }
30
+ catch {
31
+ return '/';
32
+ }
33
+ }
34
+ function passesGate(hit) {
35
+ return hit.score >= exports.THRESHOLD && hit.margin >= exports.MARGIN;
36
+ }
37
+ function safeParse(s) {
38
+ if (typeof s !== 'string')
39
+ return null;
40
+ try {
41
+ return JSON.parse(s);
42
+ }
43
+ catch {
44
+ return null;
45
+ }
46
+ }
47
+ /** Fire-and-forget: fingerprint the just-resolved element and persist it. Never throws. */
48
+ async function captureOnResolve(evalFn, url, selector) {
49
+ try {
50
+ const raw = await evalFn((0, page_scripts_1.captureExpr)(selector));
51
+ const fp = safeParse(raw);
52
+ if (!fp)
53
+ return;
54
+ const domain = domainOf(url), route = routeOf(url);
55
+ const existing = (0, store_1.getRecord)(domain, route, selector);
56
+ const now = Date.now();
57
+ const rec = {
58
+ ...fp, selector,
59
+ capturedAt: existing?.capturedAt ?? now,
60
+ lastSeenAt: now,
61
+ hits: (existing?.hits ?? 0) + 1,
62
+ };
63
+ (0, store_1.putRecord)(domain, route, selector, rec);
64
+ }
65
+ catch {
66
+ /* capture is best-effort; never disrupt the resolve */
67
+ }
68
+ }
69
+ /**
70
+ * Capture an element resolved inside a child frame (iframe). The top-frame capture path
71
+ * (`resolveWithHealing`) can't see iframe elements because it evals against the top frame,
72
+ * so `getCenterInFrame`'s frame-walk fallback calls this with an `evalFn` already bound to
73
+ * the child frame's execution context. Gated + fire-and-forget; never throws.
74
+ */
75
+ async function captureInContext(evalInContext, url, selector) {
76
+ if (!index_1.experimentRegistry.isEnabled('fingerprinting'))
77
+ return;
78
+ await captureOnResolve(evalInContext, url, selector);
79
+ }
80
+ /** On a selector miss, try to heal via stored fingerprint. Returns the attempt detail; `hit` is set only when the gate passes. */
81
+ async function healOnMiss(evalFn, url, selector) {
82
+ const rec = (0, store_1.getRecord)(domainOf(url), routeOf(url), selector);
83
+ if (!rec)
84
+ return { hadRecord: false, score: null, margin: null, hit: null };
85
+ const raw = await evalFn((0, page_scripts_1.scoreExpr)(JSON.stringify(rec)));
86
+ const scored = safeParse(raw);
87
+ if (!scored)
88
+ return { hadRecord: true, score: null, margin: null, hit: null };
89
+ return { hadRecord: true, score: scored.score, margin: scored.margin, hit: passesGate(scored) ? scored : null };
90
+ }
91
+ /**
92
+ * Heal a selector miss inside a child frame (iframe). The top-frame heal path
93
+ * (`resolveWithHealing`) evals against the top frame, so it can't see iframe
94
+ * elements; `getCenterInFrame`'s frame-walk fallback calls this with an `evalFn`
95
+ * already bound to a child frame's execution context. Returns the gate-passing
96
+ * hit's **iframe-local** center + score/margin (the caller translates to
97
+ * top-frame coords), or null when there's no record / the gate fails. Gated;
98
+ * never throws.
99
+ */
100
+ async function healInContext(evalInContext, url, selector) {
101
+ if (!index_1.experimentRegistry.isEnabled('fingerprinting'))
102
+ return null;
103
+ try {
104
+ const attempt = await healOnMiss(evalInContext, url, selector);
105
+ return attempt.hit; // non-null ONLY when the gate passed
106
+ }
107
+ catch {
108
+ return null;
109
+ }
110
+ }
111
+ /**
112
+ * Drop-in wrapper for getElementCenter. When the experiment is OFF, behaves identically
113
+ * to getElementCenter. When ON: captures on success, heals on miss, escalates (rethrows)
114
+ * if healing fails.
115
+ */
116
+ async function resolveWithHealing(evalFn, selector, getUrl, emit) {
117
+ if (!index_1.experimentRegistry.isEnabled('fingerprinting')) {
118
+ return (0, element_resolver_1.getElementCenter)(evalFn, selector);
119
+ }
120
+ const url = getUrl();
121
+ const domain = domainOf(url), route = routeOf(url);
122
+ const fire = (outcome, score, margin, hadRecord) => {
123
+ try {
124
+ emit?.({ event: 'fingerprint', outcome, selector, domain, route, score, margin, hadRecord });
125
+ }
126
+ catch { /* telemetry must never break a resolve */ }
127
+ };
128
+ try {
129
+ const center = await (0, element_resolver_1.getElementCenter)(evalFn, selector);
130
+ // fire-and-forget capture; do not await (keeps resolve latency unchanged)
131
+ void captureOnResolve(evalFn, url, selector);
132
+ fire('resolved', null, null, false);
133
+ return center;
134
+ }
135
+ catch (missErr) {
136
+ try {
137
+ const attempt = await healOnMiss(evalFn, url, selector);
138
+ if (attempt.hit) {
139
+ fire('healed', attempt.score, attempt.margin, true);
140
+ return { x: attempt.hit.cx, y: attempt.hit.cy };
141
+ }
142
+ fire('escalated', attempt.score, attempt.margin, attempt.hadRecord);
143
+ }
144
+ catch {
145
+ fire('escalated', null, null, false);
146
+ }
147
+ throw missErr; // escalate = original "Element not found" error
148
+ }
149
+ }
150
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/experimental/fingerprinting/index.ts"],"names":[],"mappings":";;;AAUA,4BAEC;AACD,0BAEC;AAED,gCAEC;AAQD,4CAkBC;AAQD,4CAGC;AAWD,gCAOC;AAWD,sCAQC;AAoBD,gDAiCC;AAjJD,uEAAoE;AACpE,oCAA8C;AAC9C,mCAA+C;AAC/C,iDAAwD;AAG3C,QAAA,SAAS,GAAG,GAAG,CAAC;AAChB,QAAA,MAAM,GAAG,IAAI,CAAC;AAE3B,SAAgB,QAAQ,CAAC,GAAuB;IAC9C,IAAI,CAAC;QAAC,OAAO,IAAI,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,SAAS,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,SAAS,CAAC;IAAC,CAAC;AAC5G,CAAC;AACD,SAAgB,OAAO,CAAC,GAAuB;IAC7C,IAAI,CAAC;QAAC,OAAO,IAAI,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,QAAQ,IAAI,GAAG,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,GAAG,CAAC;IAAC,CAAC;AAC1E,CAAC;AAED,SAAgB,UAAU,CAAC,GAAa;IACtC,OAAO,GAAG,CAAC,KAAK,IAAI,iBAAS,IAAI,GAAG,CAAC,MAAM,IAAI,cAAM,CAAC;AACxD,CAAC;AAED,SAAS,SAAS,CAAI,CAAM;IAC1B,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACvC,IAAI,CAAC;QAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAM,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;AAC3D,CAAC;AAED,2FAA2F;AACpF,KAAK,UAAU,gBAAgB,CAAC,MAAc,EAAE,GAAuB,EAAE,QAAgB;IAC9F,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAA,0BAAW,EAAC,QAAQ,CAAC,CAAC,CAAC;QAChD,MAAM,EAAE,GAAG,SAAS,CAAc,GAAG,CAAC,CAAC;QACvC,IAAI,CAAC,EAAE;YAAE,OAAO;QAChB,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QACnD,MAAM,QAAQ,GAAG,IAAA,iBAAS,EAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;QACpD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,GAAG,GAAsB;YAC7B,GAAG,EAAE,EAAE,QAAQ;YACf,UAAU,EAAE,QAAQ,EAAE,UAAU,IAAI,GAAG;YACvC,UAAU,EAAE,GAAG;YACf,IAAI,EAAE,CAAC,QAAQ,EAAE,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC;SAChC,CAAC;QACF,IAAA,iBAAS,EAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,uDAAuD;IACzD,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACI,KAAK,UAAU,gBAAgB,CAAC,aAAqB,EAAE,GAAuB,EAAE,QAAgB;IACrG,IAAI,CAAC,0BAAkB,CAAC,SAAS,CAAC,gBAAgB,CAAC;QAAE,OAAO;IAC5D,MAAM,gBAAgB,CAAC,aAAa,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;AACvD,CAAC;AAUD,kIAAkI;AAC3H,KAAK,UAAU,UAAU,CAAC,MAAc,EAAE,GAAuB,EAAE,QAAgB;IACxF,MAAM,GAAG,GAAG,IAAA,iBAAS,EAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC7D,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;IAC5E,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAA,wBAAS,EAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,SAAS,CAAW,GAAG,CAAC,CAAC;IACxC,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;IAC9E,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AAClH,CAAC;AAED;;;;;;;;GAQG;AACI,KAAK,UAAU,aAAa,CAAC,aAAqB,EAAE,GAAuB,EAAE,QAAgB;IAClG,IAAI,CAAC,0BAAkB,CAAC,SAAS,CAAC,gBAAgB,CAAC;QAAE,OAAO,IAAI,CAAC;IACjE,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,aAAa,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;QAC/D,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,qCAAqC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAeD;;;;GAIG;AACI,KAAK,UAAU,kBAAkB,CACtC,MAAc,EACd,QAAgB,EAChB,MAAgC,EAChC,IAAe;IAEf,IAAI,CAAC,0BAAkB,CAAC,SAAS,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACpD,OAAO,IAAA,mCAAgB,EAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC5C,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC;IACrB,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACnD,MAAM,IAAI,GAAG,CAAC,OAA6B,EAAE,KAAoB,EAAE,MAAqB,EAAE,SAAkB,EAAE,EAAE;QAC9G,IAAI,CAAC;YAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,0CAA0C,CAAC,CAAC;IAC5J,CAAC,CAAC;IACF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,IAAA,mCAAgB,EAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACxD,0EAA0E;QAC1E,KAAK,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;QAC7C,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QACpC,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,OAAO,EAAE,CAAC;QACjB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;YACxD,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;gBAChB,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;gBACpD,OAAO,EAAE,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YAClD,CAAC;YACD,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QACtE,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QACvC,CAAC;QACD,MAAM,OAAO,CAAC,CAAC,gDAAgD;IACjE,CAAC;AACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ /** Build a read-only IIFE that fingerprints the element matching `selector`, or returns null.
2
+ * Uses getSelectorExpression (not raw querySelector) so SuperSurf's :has-text extension and
3
+ * digit-leading-id selectors resolve the same way the real resolver does. */
4
+ export declare function captureExpr(selector: string): string;
5
+ /** Build a read-only IIFE that scores all candidates against `targetJson`, returns best {cx,cy,score,margin} or null. */
6
+ export declare function scoreExpr(targetJson: string): string;
7
+ //# sourceMappingURL=page-scripts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-scripts.d.ts","sourceRoot":"","sources":["../../../src/experimental/fingerprinting/page-scripts.ts"],"names":[],"mappings":"AAqBA;;8EAE8E;AAC9E,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAWpD;AAED,yHAAyH;AACzH,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CA0BpD"}
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.captureExpr = captureExpr;
4
+ exports.scoreExpr = scoreExpr;
5
+ const element_resolver_1 = require("../../tools/lib/element-resolver");
6
+ // Shared in-page helpers (as a source fragment, reused by both builders).
7
+ const HELPERS = `
8
+ var SELECTOR='a,button,input,textarea,select,summary,[role=button],[role=link],[role=textbox],[role=checkbox],[role=tab],[role=menuitem],[role=option],[onclick]';
9
+ function isOutermost(el){var p=el.parentElement;while(p&&p.tagName.toLowerCase()!=='body'){if(p.matches(SELECTOR))return false;p=p.parentElement;}return true;}
10
+ var TAG_ROLE={a:'link',button:'button',textarea:'textbox',select:'combobox',summary:'button'};
11
+ function roleOf(el){var r=el.getAttribute('role');if(r)return r;var t=el.tagName.toLowerCase();if(t==='input'){var ty=(el.getAttribute('type')||'text').toLowerCase();if(ty==='checkbox')return 'checkbox';if(ty==='radio')return 'radio';if(ty==='submit'||ty==='button')return 'button';return 'textbox';}return TAG_ROLE[t]||'generic';}
12
+ function directText(el){var s='';el.childNodes.forEach(function(n){if(n.nodeType===3)s+=n.textContent||'';});return s.trim().replace(/\\s+/g,' ').slice(0,120);}
13
+ function accName(el){var ity=el.tagName.toLowerCase()==='input'?(el.getAttribute('type')||'text').toLowerCase():'';var lblVal=(ity==='radio'||ity==='checkbox'||ity==='submit'||ity==='button')?(el.getAttribute('value')||''):'';var own=(el.getAttribute('aria-label')||el.getAttribute('alt')||el.getAttribute('placeholder')||lblVal).trim();if(own)return own.slice(0,120);var dt=directText(el);if(dt)return dt.slice(0,120);var imgs=el.querySelectorAll('img[alt]');for(var i=0;i<imgs.length;i++){var a=(imgs[i].getAttribute('alt')||'').trim();if(a)return a.slice(0,120);}var lab=el.querySelectorAll('[aria-label]');for(var j=0;j<lab.length;j++){var la=(lab[j].getAttribute('aria-label')||'').trim();if(la)return la.slice(0,120);}return (el.textContent||'').trim().replace(/\\s+/g,' ').slice(0,120);}
14
+ var STABLE=/^(data-(testid|test-id|test|automation-id|id|key|item-id|qa|cy)|aria-label|name|placeholder|alt|title)$/;
15
+ function stableAttrs(el){var o={};Array.from(el.attributes).forEach(function(a){if(a.name==='data-poc-truth')return;if(STABLE.test(a.name)&&a.value)o[a.name]=a.value;});return o;}
16
+ function classList(el){var c=el.getAttribute('class');return c?c.trim().split(/\\s+/).filter(Boolean).slice(0,6):[];}
17
+ function center(el){var r=el.getBoundingClientRect();return {x:Math.round(r.left+r.width/2),y:Math.round(r.top+r.height/2)};}
18
+ var LANDMARK=/^(nav|main|header|footer|aside|form|section)$/;
19
+ function landmark(el){var c=el.parentElement;while(c&&c.tagName.toLowerCase()!=='body'){var t=c.tagName.toLowerCase();var r=c.getAttribute('role');if(LANDMARK.test(t)||r)return (r||t)+':'+((c.getAttribute('aria-label')||'').slice(0,40));c=c.parentElement;}return '';}
20
+ var ALL=Array.from(document.querySelectorAll(SELECTOR)).filter(isOutermost).map(function(el){return {el:el,c:center(el)};});
21
+ function neighborText(el,c){var out=[];ALL.forEach(function(o){if(o.el===el)return;var dx=o.c.x-c.x,dy=o.c.y-c.y;if(dx*dx+dy*dy<140*140){var t=directText(o.el);if(t)out.push(t);}});return out.join(' ').slice(0,160);}
22
+ function fp(el,c){var role=roleOf(el);return {role:role,name:accName(el),text:directText(el),tag:el.tagName.toLowerCase(),type:el.getAttribute('type')||null,attrs:stableAttrs(el),classList:classList(el),htmlId:el.id||'',cx:c.x,cy:c.y,neighborText:neighborText(el,c),landmark:landmark(el)};}
23
+ `;
24
+ /** Build a read-only IIFE that fingerprints the element matching `selector`, or returns null.
25
+ * Uses getSelectorExpression (not raw querySelector) so SuperSurf's :has-text extension and
26
+ * digit-leading-id selectors resolve the same way the real resolver does. */
27
+ function captureExpr(selector) {
28
+ const elExpr = (0, element_resolver_1.getSelectorExpression)(selector);
29
+ return `(function(){${HELPERS}
30
+ var el; try { el = (${elExpr}); } catch(e){ el = null; }
31
+ if(!el) return null;
32
+ var c=center(el);
33
+ var role=roleOf(el);
34
+ var rc=0; for(var k=0;k<ALL.length;k++){ if(roleOf(ALL[k].el)===role){ if(ALL[k].el===el) break; rc++; } }
35
+ var f=fp(el,c); f.ordinal=rc;
36
+ return JSON.stringify(f);
37
+ })()`;
38
+ }
39
+ /** Build a read-only IIFE that scores all candidates against `targetJson`, returns best {cx,cy,score,margin} or null. */
40
+ function scoreExpr(targetJson) {
41
+ return `(function(){${HELPERS}
42
+ var T=${targetJson};
43
+ var W={name:28,text:18,role:14,neighborText:14,landmark:8,position:8,tag:6,type:3,classList:5,htmlId:3,attrs:6,ordinal:3};
44
+ function tokens(s){return (s||'').toLowerCase().split(/\\s+/).filter(Boolean);}
45
+ function jac(a,b){if(!a.length&&!b.length)return 1;var sb=new Set(b),i=0;new Set(a).forEach(function(x){if(sb.has(x))i++;});var u=new Set(a.concat(b)).size;return u?i/u:0;}
46
+ function ov(a,b){var k=Object.keys(a);if(!k.length)return 0;var m=0;k.forEach(function(x){if(b[x]===a[x])m++;});return m/k.length;}
47
+ var rc={};
48
+ var cands=ALL.map(function(o){var el=o.el,c=o.c;var role=roleOf(el);var ord=(rc[role]=(rc[role]||0)+1)-1;var f=fp(el,c);f.ordinal=ord;f.cx=c.x;f.cy=c.y;return f;});
49
+ function sc(t,c){var got=0,max=0;function add(w,h){max+=w;got+=w*h;}
50
+ if(t.name)add(W.name,t.name===c.name?1:(c.name&&(c.name.indexOf(t.name)>=0||t.name.indexOf(c.name)>=0)?0.5:0));
51
+ if(t.text)add(W.text,t.text===c.text?1:(c.text.indexOf(t.text)>=0?0.5:0));
52
+ add(W.role,t.role===c.role?1:0);
53
+ if(t.neighborText)add(W.neighborText,jac(tokens(t.neighborText),tokens(c.neighborText)));
54
+ if(t.landmark)add(W.landmark,t.landmark===c.landmark?1:(c.landmark&&c.landmark.split(':')[0]===t.landmark.split(':')[0]?0.5:0));
55
+ var d=Math.hypot((t.cx||0)-c.cx,(t.cy||0)-c.cy);add(W.position,Math.max(0,1-d/600));
56
+ add(W.tag,t.tag===c.tag?1:0);if(t.type)add(W.type,t.type===c.type?1:0);
57
+ if(t.classList&&t.classList.length)add(W.classList,jac(t.classList,c.classList));
58
+ if(t.htmlId)add(W.htmlId,t.htmlId===c.htmlId?1:0);
59
+ if(t.attrs&&Object.keys(t.attrs).length)add(W.attrs,ov(t.attrs,c.attrs));
60
+ add(W.ordinal,t.ordinal===c.ordinal?1:0);return max?got/max:0;}
61
+ var best=null,bs=0,ru=0;
62
+ cands.forEach(function(c){var s=sc(T,c);if(s>bs){ru=bs;bs=s;best=c;}else if(s>ru)ru=s;});
63
+ if(!best) return null;
64
+ return JSON.stringify({cx:best.cx,cy:best.cy,score:+bs.toFixed(3),margin:+(bs-ru).toFixed(3)});
65
+ })()`;
66
+ }
67
+ //# sourceMappingURL=page-scripts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-scripts.js","sourceRoot":"","sources":["../../../src/experimental/fingerprinting/page-scripts.ts"],"names":[],"mappings":";;AAwBA,kCAWC;AAGD,8BA0BC;AAhED,uEAAyE;AAEzE,0EAA0E;AAC1E,MAAM,OAAO,GAAG;;;;;;;;;;;;;;;;CAgBf,CAAC;AAEF;;8EAE8E;AAC9E,SAAgB,WAAW,CAAC,QAAgB;IAC1C,MAAM,MAAM,GAAG,IAAA,wCAAqB,EAAC,QAAQ,CAAC,CAAC;IAC/C,OAAO,eAAe,OAAO;0BACL,MAAM;;;;;;;OAOzB,CAAC;AACR,CAAC;AAED,yHAAyH;AACzH,SAAgB,SAAS,CAAC,UAAkB;IAC1C,OAAO,eAAe,OAAO;YACnB,UAAU;;;;;;;;;;;;;;;;;;;;;;;OAuBf,CAAC;AACR,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { DomainStore, FingerprintRecord } from './types';
2
+ /** Test-only override of the storage directory. */
3
+ export declare function setBaseDirForTests(dir: string): void;
4
+ export declare function loadDomain(domain: string): DomainStore;
5
+ export declare function saveDomain(store: DomainStore): void;
6
+ export declare function getRecord(domain: string, route: string, selector: string): FingerprintRecord | undefined;
7
+ export declare function putRecord(domain: string, route: string, selector: string, rec: FingerprintRecord): void;
8
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/experimental/fingerprinting/store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAI9D,mDAAmD;AACnD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEpD;AAQD,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,CAMtD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAGnD;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAIxG;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,iBAAiB,GAAG,IAAI,CAKvG"}
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.setBaseDirForTests = setBaseDirForTests;
37
+ exports.loadDomain = loadDomain;
38
+ exports.saveDomain = saveDomain;
39
+ exports.getRecord = getRecord;
40
+ exports.putRecord = putRecord;
41
+ const fs = __importStar(require("node:fs"));
42
+ const path = __importStar(require("node:path"));
43
+ const os = __importStar(require("node:os"));
44
+ let baseDir = path.join(os.homedir(), '.supersurf', 'fingerprints');
45
+ /** Test-only override of the storage directory. */
46
+ function setBaseDirForTests(dir) {
47
+ baseDir = dir;
48
+ }
49
+ function domainFile(domain) {
50
+ // domain is a hostname; safe as a filename. Strip anything odd defensively.
51
+ const safe = domain.replace(/[^a-zA-Z0-9._-]/g, '_');
52
+ return path.join(baseDir, `${safe}.json`);
53
+ }
54
+ function loadDomain(domain) {
55
+ try {
56
+ return JSON.parse(fs.readFileSync(domainFile(domain), 'utf8'));
57
+ }
58
+ catch {
59
+ return { domain, routes: {} };
60
+ }
61
+ }
62
+ function saveDomain(store) {
63
+ fs.mkdirSync(baseDir, { recursive: true });
64
+ fs.writeFileSync(domainFile(store.domain), JSON.stringify(store, null, 2));
65
+ }
66
+ function getRecord(domain, route, selector) {
67
+ const store = loadDomain(domain);
68
+ const byRoute = store.routes[route];
69
+ return byRoute ? byRoute[selector] : undefined;
70
+ }
71
+ function putRecord(domain, route, selector, rec) {
72
+ const store = loadDomain(domain);
73
+ if (!store.routes[route])
74
+ store.routes[route] = {};
75
+ store.routes[route][selector] = rec;
76
+ saveDomain(store);
77
+ }
78
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/experimental/fingerprinting/store.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,gDAEC;AAQD,gCAMC;AAED,gCAGC;AAED,8BAIC;AAED,8BAKC;AA1CD,4CAA8B;AAC9B,gDAAkC;AAClC,4CAA8B;AAG9B,IAAI,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,YAAY,EAAE,cAAc,CAAC,CAAC;AAEpE,mDAAmD;AACnD,SAAgB,kBAAkB,CAAC,GAAW;IAC5C,OAAO,GAAG,GAAG,CAAC;AAChB,CAAC;AAED,SAAS,UAAU,CAAC,MAAc;IAChC,4EAA4E;IAC5E,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;IACrD,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED,SAAgB,UAAU,CAAC,MAAc;IACvC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAgB,CAAC;IAChF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAChC,CAAC;AACH,CAAC;AAED,SAAgB,UAAU,CAAC,KAAkB;IAC3C,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,EAAE,CAAC,aAAa,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED,SAAgB,SAAS,CAAC,MAAc,EAAE,KAAa,EAAE,QAAgB;IACvE,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IACjC,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACpC,OAAO,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACjD,CAAC;AAED,SAAgB,SAAS,CAAC,MAAc,EAAE,KAAa,EAAE,QAAgB,EAAE,GAAsB;IAC/F,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC;QAAE,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;IACnD,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC;IACpC,UAAU,CAAC,KAAK,CAAC,CAAC;AACpB,CAAC"}
@@ -0,0 +1,32 @@
1
+ export interface Fingerprint {
2
+ role: string;
3
+ name: string;
4
+ text: string;
5
+ tag: string;
6
+ type: string | null;
7
+ attrs: Record<string, string>;
8
+ classList: string[];
9
+ htmlId: string;
10
+ ordinal: number;
11
+ cx: number;
12
+ cy: number;
13
+ neighborText: string;
14
+ landmark: string;
15
+ }
16
+ export interface FingerprintRecord extends Fingerprint {
17
+ selector: string;
18
+ capturedAt: number;
19
+ lastSeenAt: number;
20
+ hits: number;
21
+ }
22
+ export interface DomainStore {
23
+ domain: string;
24
+ routes: Record<string, Record<string, FingerprintRecord>>;
25
+ }
26
+ export interface ScoreHit {
27
+ cx: number;
28
+ cy: number;
29
+ score: number;
30
+ margin: number;
31
+ }
32
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/experimental/fingerprinting/types.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAkB,SAAQ,WAAW;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC;CAC3D;AAGD,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/experimental/fingerprinting/types.ts"],"names":[],"mappings":""}
@@ -26,7 +26,7 @@ Object.defineProperty(exports, "calculateConfidence", { enumerable: true, get: f
26
26
  Object.defineProperty(exports, "formatDiffSection", { enumerable: true, get: function () { return page_diffing_1.formatDiffSection; } });
27
27
  const storage_inspection_1 = require("./storage-inspection");
28
28
  /** All recognized session-toggleable experiment names. */
29
- const AVAILABLE_EXPERIMENTS = ['page_diffing', 'smart_waiting', 'storage_inspection', 'mouse_humanization'];
29
+ const AVAILABLE_EXPERIMENTS = ['page_diffing', 'smart_waiting', 'storage_inspection', 'mouse_humanization', 'fingerprinting'];
30
30
  /**
31
31
  * Cache-backed IPC proxy for experiment state.
32
32
  *
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/experimental/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/experimental/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Action recorder — records what each interaction action targeted and what
3
+ * happened, to the usage-metrics trail. Config-gated (logging.action_recording),
4
+ * core infra (NOT an experiment). Records only; downstream tooling
5
+ * (fingerprinting / self-healing) consumes this chokepoint separately.
6
+ *
7
+ * @module recorder/action-recorder
8
+ */
9
+ /** One recorded interaction action: its target and outcome. */
10
+ export interface ActionRecord {
11
+ event: 'action';
12
+ type: string;
13
+ selector: string | null;
14
+ x: number | null;
15
+ y: number | null;
16
+ outcome: 'ok' | 'error';
17
+ message: string | null;
18
+ duration_ms: number;
19
+ }
20
+ /**
21
+ * Record one action's target + outcome. Called from executeAction on both the
22
+ * success and error paths. Gated by logging.action_recording. NEVER throws.
23
+ */
24
+ export declare function recordAction(ctx: any, action: any, startedAt: number, result: string | null, error: unknown): void;
25
+ //# sourceMappingURL=action-recorder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-recorder.d.ts","sourceRoot":"","sources":["../../src/recorder/action-recorder.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,+DAA+D;AAC/D,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,QAAQ,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjB,OAAO,EAAE,IAAI,GAAG,OAAO,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACrB;AAMD;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,GAAG,EACX,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,KAAK,EAAE,OAAO,GACb,IAAI,CA0BN"}
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ /**
3
+ * Action recorder — records what each interaction action targeted and what
4
+ * happened, to the usage-metrics trail. Config-gated (logging.action_recording),
5
+ * core infra (NOT an experiment). Records only; downstream tooling
6
+ * (fingerprinting / self-healing) consumes this chokepoint separately.
7
+ *
8
+ * @module recorder/action-recorder
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.recordAction = recordAction;
12
+ function truncate(s, n = 200) {
13
+ return s.length > n ? s.slice(0, n) + '…' : s;
14
+ }
15
+ /**
16
+ * Record one action's target + outcome. Called from executeAction on both the
17
+ * success and error paths. Gated by logging.action_recording. NEVER throws.
18
+ */
19
+ function recordAction(ctx, action, startedAt, result, error) {
20
+ try {
21
+ if (ctx?.config?.get?.()?.logging?.action_recording !== true)
22
+ return;
23
+ const rec = {
24
+ event: 'action',
25
+ type: typeof action?.type === 'string' ? action.type : 'unknown',
26
+ selector: typeof action?.selector === 'string' ? action.selector : null,
27
+ x: typeof action?.x === 'number' ? action.x : null,
28
+ y: typeof action?.y === 'number' ? action.y : null,
29
+ outcome: error ? 'error' : 'ok',
30
+ message: error
31
+ ? truncate(error instanceof Error ? error.message : String(error))
32
+ : (typeof result === 'string' ? truncate(result) : null),
33
+ duration_ms: Date.now() - startedAt,
34
+ };
35
+ ctx?.metricsLogger?.write({
36
+ session_id: ctx?.connectionManager?.clientId ?? 'unknown',
37
+ tool: 'action',
38
+ params: rec,
39
+ result: rec.outcome,
40
+ url: ctx?.connectionManager?.getAttachedTab?.()?.url,
41
+ duration_ms: rec.duration_ms,
42
+ });
43
+ }
44
+ catch {
45
+ /* recorder is best-effort; never disrupt the interaction */
46
+ }
47
+ }
48
+ //# sourceMappingURL=action-recorder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-recorder.js","sourceRoot":"","sources":["../../src/recorder/action-recorder.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AAsBH,oCAgCC;AAxCD,SAAS,QAAQ,CAAC,CAAS,EAAE,CAAC,GAAG,GAAG;IAClC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAChD,CAAC;AAED;;;GAGG;AACH,SAAgB,YAAY,CAC1B,GAAQ,EACR,MAAW,EACX,SAAiB,EACjB,MAAqB,EACrB,KAAc;IAEd,IAAI,CAAC;QACH,IAAI,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,gBAAgB,KAAK,IAAI;YAAE,OAAO;QACrE,MAAM,GAAG,GAAiB;YACxB,KAAK,EAAE,QAAQ;YACf,IAAI,EAAE,OAAO,MAAM,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;YAChE,QAAQ,EAAE,OAAO,MAAM,EAAE,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI;YACvE,CAAC,EAAE,OAAO,MAAM,EAAE,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI;YAClD,CAAC,EAAE,OAAO,MAAM,EAAE,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI;YAClD,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;YAC/B,OAAO,EAAE,KAAK;gBACZ,CAAC,CAAC,QAAQ,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAClE,CAAC,CAAC,CAAC,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC1D,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;SACpC,CAAC;QACF,GAAG,EAAE,aAAa,EAAE,KAAK,CAAC;YACxB,UAAU,EAAE,GAAG,EAAE,iBAAiB,EAAE,QAAQ,IAAI,SAAS;YACzD,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,GAAyC;YACjD,MAAM,EAAE,GAAG,CAAC,OAAO;YACnB,GAAG,EAAE,GAAG,EAAE,iBAAiB,EAAE,cAAc,EAAE,EAAE,EAAE,GAAG;YACpD,WAAW,EAAE,GAAG,CAAC,WAAW;SAC7B,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,4DAA4D;IAC9D,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../config/defaults.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtC,eAAO,MAAM,kBAAkB,EAAE,MA6BhC,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,MAY/B,CAAC"}
1
+ {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../config/defaults.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtC,eAAO,MAAM,kBAAkB,EAAE,MA+BhC,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,MAY/B,CAAC"}
@@ -7,6 +7,7 @@ exports.HARDCODED_DEFAULTS = {
7
7
  smart_waiting: false,
8
8
  storage_inspection: false,
9
9
  mouse_humanization: false,
10
+ fingerprinting: false,
10
11
  },
11
12
  security: {
12
13
  secure_eval: true,
@@ -23,6 +24,7 @@ exports.HARDCODED_DEFAULTS = {
23
24
  logging: {
24
25
  debug: false,
25
26
  usage_metrics: false,
27
+ action_recording: false,
26
28
  },
27
29
  profiles: {
28
30
  startup_opts: {
@@ -39,7 +41,7 @@ exports.SCAFFOLD_DEFAULTS = {
39
41
  domain_whitelist: { ...exports.HARDCODED_DEFAULTS.security.domain_whitelist, custom: [] },
40
42
  },
41
43
  daemon: { ...exports.HARDCODED_DEFAULTS.daemon },
42
- logging: { ...exports.HARDCODED_DEFAULTS.logging, usage_metrics: true },
44
+ logging: { ...exports.HARDCODED_DEFAULTS.logging, usage_metrics: true, action_recording: false },
43
45
  profiles: {
44
46
  startup_opts: { ...exports.HARDCODED_DEFAULTS.profiles.startup_opts },
45
47
  },
@@ -1 +1 @@
1
- {"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../config/defaults.ts"],"names":[],"mappings":";;;AAEa,QAAA,kBAAkB,GAAW;IACxC,WAAW,EAAE;QACX,YAAY,EAAE,KAAK;QACnB,aAAa,EAAE,KAAK;QACpB,kBAAkB,EAAE,KAAK;QACzB,kBAAkB,EAAE,KAAK;KAC1B;IACD,QAAQ,EAAE;QACR,WAAW,EAAE,IAAI;QACjB,gBAAgB,EAAE;YAChB,OAAO,EAAE,KAAK;YACd,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,EAAE;SACX;KACF;IACD,MAAM,EAAE;QACN,IAAI,EAAE,IAAI;QACV,eAAe,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;KAChC;IACD,OAAO,EAAE;QACP,KAAK,EAAE,KAAK;QACZ,aAAa,EAAE,KAAK;KACrB;IACD,QAAQ,EAAE;QACR,YAAY,EAAE;YACZ,WAAW,EAAE,KAAK;SACnB;KACF;IACD,IAAI,EAAE,IAAI;CACX,CAAC;AAEW,QAAA,iBAAiB,GAAW;IACvC,GAAG,0BAAkB;IACrB,WAAW,EAAE,EAAE,GAAG,0BAAkB,CAAC,WAAW,EAAE;IAClD,QAAQ,EAAE;QACR,GAAG,0BAAkB,CAAC,QAAQ;QAC9B,gBAAgB,EAAE,EAAE,GAAG,0BAAkB,CAAC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,EAAE,EAAE,EAAE;KAClF;IACD,MAAM,EAAE,EAAE,GAAG,0BAAkB,CAAC,MAAM,EAAE;IACxC,OAAO,EAAE,EAAE,GAAG,0BAAkB,CAAC,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE;IAC/D,QAAQ,EAAE;QACR,YAAY,EAAE,EAAE,GAAG,0BAAkB,CAAC,QAAQ,CAAC,YAAY,EAAE;KAC9D;CACF,CAAC"}
1
+ {"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../config/defaults.ts"],"names":[],"mappings":";;;AAEa,QAAA,kBAAkB,GAAW;IACxC,WAAW,EAAE;QACX,YAAY,EAAE,KAAK;QACnB,aAAa,EAAE,KAAK;QACpB,kBAAkB,EAAE,KAAK;QACzB,kBAAkB,EAAE,KAAK;QACzB,cAAc,EAAE,KAAK;KACtB;IACD,QAAQ,EAAE;QACR,WAAW,EAAE,IAAI;QACjB,gBAAgB,EAAE;YAChB,OAAO,EAAE,KAAK;YACd,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,EAAE;SACX;KACF;IACD,MAAM,EAAE;QACN,IAAI,EAAE,IAAI;QACV,eAAe,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;KAChC;IACD,OAAO,EAAE;QACP,KAAK,EAAE,KAAK;QACZ,aAAa,EAAE,KAAK;QACpB,gBAAgB,EAAE,KAAK;KACxB;IACD,QAAQ,EAAE;QACR,YAAY,EAAE;YACZ,WAAW,EAAE,KAAK;SACnB;KACF;IACD,IAAI,EAAE,IAAI;CACX,CAAC;AAEW,QAAA,iBAAiB,GAAW;IACvC,GAAG,0BAAkB;IACrB,WAAW,EAAE,EAAE,GAAG,0BAAkB,CAAC,WAAW,EAAE;IAClD,QAAQ,EAAE;QACR,GAAG,0BAAkB,CAAC,QAAQ;QAC9B,gBAAgB,EAAE,EAAE,GAAG,0BAAkB,CAAC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,EAAE,EAAE,EAAE;KAClF;IACD,MAAM,EAAE,EAAE,GAAG,0BAAkB,CAAC,MAAM,EAAE;IACxC,OAAO,EAAE,EAAE,GAAG,0BAAkB,CAAC,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE;IACxF,QAAQ,EAAE;QACR,YAAY,EAAE,EAAE,GAAG,0BAAkB,CAAC,QAAQ,CAAC,YAAY,EAAE;KAC9D;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"loaders.d.ts","sourceRoot":"","sources":["../../config/loaders.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAU,aAAa,EAAE,MAAM,SAAS,CAAC;AAErD,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CA0B3D;AAqBD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,UAAU,CA0CjF"}
1
+ {"version":3,"file":"loaders.d.ts","sourceRoot":"","sources":["../../config/loaders.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAU,aAAa,EAAE,MAAM,SAAS,CAAC;AAErD,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CA0B3D;AAkBD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,UAAU,CA0CjF"}
@@ -66,10 +66,7 @@ function loadJsonConfig(filePath) {
66
66
  return { config: parsed, warnings: [] };
67
67
  }
68
68
  const KNOWN_EXPERIMENTS = [
69
- 'page_diffing',
70
- 'smart_waiting',
71
- 'storage_inspection',
72
- 'mouse_humanization',
69
+ 'page_diffing', 'smart_waiting', 'storage_inspection', 'mouse_humanization', 'fingerprinting',
73
70
  ];
74
71
  function isKnownExperiment(s) {
75
72
  return KNOWN_EXPERIMENTS.includes(s);