leapfrog-mcp 0.7.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -27,7 +27,7 @@ import { adaptiveNavigate, formatAdaptiveResult } from "./adaptive-wait.js";
27
27
  import { runStealthAudit } from "./stealth-audit.js";
28
28
  import { exportSession, replayRecording } from "./recording.js";
29
29
  import { paginate } from "./paginate.js";
30
- import { getHUDInitScript, getHUDUpdateScript, getClickRippleScript } from "./session-hud.js";
30
+ import { getHUDInitScript, getHUDUpdateScript, getClickRippleScript, getAgentEyesInitScript } from "./session-hud.js";
31
31
  import { getDetectionInitScript, getDetectionCheckScript, getResolutionCheckScript, parseDetectionResult, getPressAndHoldDetectScript, solvePressAndHold } from "./intervention.js";
32
32
  import { getConsentDismissScript, getCacheSelectorScript, getTermsAutoCheckScript } from "./consent-dismiss.js";
33
33
  import { solveCaptcha, isCaptchaSolverEnabled } from "./captcha-solver.js";
@@ -369,6 +369,8 @@ server.registerTool("session_create", {
369
369
  }
370
370
  // Always inject intervention detection (lightweight MutationObserver)
371
371
  await session.context.addInitScript(getDetectionInitScript());
372
+ // Agent eyes — cursor dot + scroll indicator (zero Node overhead, listens to native DOM events)
373
+ await session.context.addInitScript(getAgentEyesInitScript());
372
374
  attachAdBlocker(session.context);
373
375
  // Start tracing if enabled
374
376
  if (LEAP_TRACE) {
@@ -427,6 +429,7 @@ server.registerTool("session_create_batch", {
427
429
  if (LEAP_AUTO_CONSENT)
428
430
  await session.context.addInitScript(getConsentDismissScript());
429
431
  await session.context.addInitScript(getDetectionInitScript());
432
+ await session.context.addInitScript(getAgentEyesInitScript());
430
433
  attachAdBlocker(session.context);
431
434
  if (LEAP_TRACE)
432
435
  await session.context.tracing.start({ screenshots: true, snapshots: true });
@@ -16,5 +16,11 @@ export declare function getClickRippleScript(x: number, y: number): string;
16
16
  */
17
17
  export declare function getScrollToTargetZoomIn(selector: string): string;
18
18
  export declare function getScrollToTargetZoomOut(selector: string): string;
19
+ /**
20
+ * Returns JS to inject cursor tracking + scroll indicator for headed sessions.
21
+ * Always-on for headed mode — not gated by LEAP_HUD.
22
+ * Zero Node.js overhead: listens to native DOM events dispatched by Playwright.
23
+ */
24
+ export declare function getAgentEyesInitScript(): string;
19
25
  /** Legacy single-call version (sync scroll only, no zoom). */
20
26
  export declare function getScrollToTargetScript(selector: string): string;
@@ -79,6 +79,7 @@ export function getHUDInitScript(sessionName) {
79
79
  container.appendChild(ripple);
80
80
  ripple.addEventListener('animationend', function() { ripple.remove(); });
81
81
  };
82
+
82
83
  })();`;
83
84
  }
84
85
  // ─── Live Update Scripts ───────────────────────────────────────────────────
@@ -124,6 +125,117 @@ export function getScrollToTargetZoomOut(selector) {
124
125
  }
125
126
  })()`;
126
127
  }
128
+ // ─── Agent Eyes Init Script ───────────────────────────────────────────────
129
+ /**
130
+ * Returns JS to inject cursor tracking + scroll indicator for headed sessions.
131
+ * Always-on for headed mode — not gated by LEAP_HUD.
132
+ * Zero Node.js overhead: listens to native DOM events dispatched by Playwright.
133
+ */
134
+ export function getAgentEyesInitScript() {
135
+ return `(function() {
136
+ if (window.__leapfrog_eyes_initialized) return;
137
+ window.__leapfrog_eyes_initialized = true;
138
+
139
+ function init() {
140
+ // ── CSS ──────────────────────────────────────────────────────────
141
+ var style = document.createElement('style');
142
+ style.setAttribute('data-leapfrog', 'true');
143
+ style.textContent = \`
144
+ #leapfrog-cursor {
145
+ position: fixed;
146
+ width: 20px;
147
+ height: 20px;
148
+ border-radius: 50%;
149
+ background: rgba(34, 197, 94, 0.8);
150
+ box-shadow: 0 0 12px rgba(34, 197, 94, 0.5), 0 0 4px rgba(34, 197, 94, 0.8);
151
+ pointer-events: none;
152
+ z-index: 2147483646;
153
+ transform: translate(-50%, -50%);
154
+ transition: left 0.04s linear, top 0.04s linear, opacity 0.3s ease;
155
+ opacity: 0;
156
+ }
157
+ #leapfrog-cursor-ring {
158
+ position: fixed;
159
+ width: 36px;
160
+ height: 36px;
161
+ border-radius: 50%;
162
+ border: 2px solid rgba(34, 197, 94, 0.4);
163
+ pointer-events: none;
164
+ z-index: 2147483646;
165
+ transform: translate(-50%, -50%);
166
+ transition: left 0.08s ease-out, top 0.08s ease-out, opacity 0.3s ease;
167
+ opacity: 0;
168
+ }
169
+ #leapfrog-scroll-indicator {
170
+ position: fixed;
171
+ right: 16px;
172
+ top: 50%;
173
+ width: 36px;
174
+ height: 36px;
175
+ border-radius: 50%;
176
+ background: rgba(34, 197, 94, 0.7);
177
+ color: #fff;
178
+ font-size: 20px;
179
+ line-height: 36px;
180
+ text-align: center;
181
+ pointer-events: none;
182
+ z-index: 2147483646;
183
+ opacity: 0;
184
+ transition: opacity 0.15s ease-out;
185
+ transform: translateY(-50%);
186
+ }
187
+ \`;
188
+ (document.head || document.documentElement).appendChild(style);
189
+
190
+ // ── Agent Cursor (dot + trailing ring) ──────────────────────────
191
+ var cursor = document.createElement('div');
192
+ cursor.id = 'leapfrog-cursor';
193
+ cursor.setAttribute('data-leapfrog', 'true');
194
+ (document.body || document.documentElement).appendChild(cursor);
195
+
196
+ var ring = document.createElement('div');
197
+ ring.id = 'leapfrog-cursor-ring';
198
+ ring.setAttribute('data-leapfrog', 'true');
199
+ (document.body || document.documentElement).appendChild(ring);
200
+
201
+ var cursorTimeout;
202
+ document.addEventListener('mousemove', function(e) {
203
+ cursor.style.left = e.clientX + 'px';
204
+ cursor.style.top = e.clientY + 'px';
205
+ cursor.style.opacity = '1';
206
+ ring.style.left = e.clientX + 'px';
207
+ ring.style.top = e.clientY + 'px';
208
+ ring.style.opacity = '1';
209
+ clearTimeout(cursorTimeout);
210
+ cursorTimeout = setTimeout(function() {
211
+ cursor.style.opacity = '0';
212
+ ring.style.opacity = '0';
213
+ }, 3000);
214
+ }, true);
215
+
216
+ // ── Scroll Indicator ────────────────────────────────────────────
217
+ var scrollArrow = document.createElement('div');
218
+ scrollArrow.id = 'leapfrog-scroll-indicator';
219
+ scrollArrow.setAttribute('data-leapfrog', 'true');
220
+ (document.body || document.documentElement).appendChild(scrollArrow);
221
+
222
+ var scrollFadeTimeout;
223
+ document.addEventListener('wheel', function(e) {
224
+ scrollArrow.textContent = e.deltaY > 0 ? '\\u25BC' : '\\u25B2';
225
+ scrollArrow.style.opacity = '1';
226
+ clearTimeout(scrollFadeTimeout);
227
+ scrollFadeTimeout = setTimeout(function() { scrollArrow.style.opacity = '0'; }, 400);
228
+ }, true);
229
+ }
230
+
231
+ // Defer until body exists — init scripts can run before DOM is ready
232
+ if (document.body) {
233
+ init();
234
+ } else {
235
+ document.addEventListener('DOMContentLoaded', init);
236
+ }
237
+ })();`;
238
+ }
127
239
  /** Legacy single-call version (sync scroll only, no zoom). */
128
240
  export function getScrollToTargetScript(selector) {
129
241
  const escaped = selector.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "leapfrog-mcp",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "Multi-session browser MCP for AI agents — 36 tools, stealth, persistent auth, code-first scripts, API sniffer, agent intelligence",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",