misoai-web 1.6.0 → 1.6.2

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 (71) hide show
  1. package/dist/es/agent.js +108 -50
  2. package/dist/es/agent.js.map +1 -1
  3. package/dist/es/bridge-mode-browser.js +3 -3
  4. package/dist/es/bridge-mode-browser.js.map +1 -1
  5. package/dist/es/bridge-mode.js +110 -52
  6. package/dist/es/bridge-mode.js.map +1 -1
  7. package/dist/es/chrome-extension.js +109 -51
  8. package/dist/es/chrome-extension.js.map +1 -1
  9. package/dist/es/index.js +425 -68
  10. package/dist/es/index.js.map +1 -1
  11. package/dist/es/midscene-playground.js +111 -53
  12. package/dist/es/midscene-playground.js.map +1 -1
  13. package/dist/es/midscene-server.js +4 -4
  14. package/dist/es/midscene-server.js.map +1 -1
  15. package/dist/es/playground.js +108 -50
  16. package/dist/es/playground.js.map +1 -1
  17. package/dist/es/playwright-report.js +1 -1
  18. package/dist/es/playwright-report.js.map +1 -1
  19. package/dist/es/playwright.js +425 -68
  20. package/dist/es/playwright.js.map +1 -1
  21. package/dist/es/puppeteer-agent-launcher.js +424 -67
  22. package/dist/es/puppeteer-agent-launcher.js.map +1 -1
  23. package/dist/es/puppeteer.js +424 -67
  24. package/dist/es/puppeteer.js.map +1 -1
  25. package/dist/es/utils.js +1 -1
  26. package/dist/es/utils.js.map +1 -1
  27. package/dist/es/yaml.js +1 -1
  28. package/dist/es/yaml.js.map +1 -1
  29. package/dist/lib/agent.js +108 -50
  30. package/dist/lib/agent.js.map +1 -1
  31. package/dist/lib/bridge-mode-browser.js +3 -3
  32. package/dist/lib/bridge-mode-browser.js.map +1 -1
  33. package/dist/lib/bridge-mode.js +110 -52
  34. package/dist/lib/bridge-mode.js.map +1 -1
  35. package/dist/lib/chrome-extension.js +109 -51
  36. package/dist/lib/chrome-extension.js.map +1 -1
  37. package/dist/lib/index.js +425 -68
  38. package/dist/lib/index.js.map +1 -1
  39. package/dist/lib/midscene-playground.js +111 -53
  40. package/dist/lib/midscene-playground.js.map +1 -1
  41. package/dist/lib/midscene-server.js +4 -4
  42. package/dist/lib/midscene-server.js.map +1 -1
  43. package/dist/lib/playground.js +108 -50
  44. package/dist/lib/playground.js.map +1 -1
  45. package/dist/lib/playwright-report.js +1 -1
  46. package/dist/lib/playwright-report.js.map +1 -1
  47. package/dist/lib/playwright.js +425 -68
  48. package/dist/lib/playwright.js.map +1 -1
  49. package/dist/lib/puppeteer-agent-launcher.js +424 -67
  50. package/dist/lib/puppeteer-agent-launcher.js.map +1 -1
  51. package/dist/lib/puppeteer.js +424 -67
  52. package/dist/lib/puppeteer.js.map +1 -1
  53. package/dist/lib/utils.js +1 -1
  54. package/dist/lib/utils.js.map +1 -1
  55. package/dist/lib/yaml.js +1 -1
  56. package/dist/lib/yaml.js.map +1 -1
  57. package/dist/types/agent.d.ts +1 -1
  58. package/dist/types/bridge-mode-browser.d.ts +2 -2
  59. package/dist/types/bridge-mode.d.ts +2 -2
  60. package/dist/types/{browser-9b472ffb.d.ts → browser-f205f69d.d.ts} +1 -1
  61. package/dist/types/chrome-extension.d.ts +2 -2
  62. package/dist/types/index.d.ts +2 -2
  63. package/dist/types/midscene-server.d.ts +1 -1
  64. package/dist/types/{page-ed0ecb44.d.ts → page-c5452809.d.ts} +45 -0
  65. package/dist/types/playground.d.ts +2 -2
  66. package/dist/types/playwright.d.ts +2 -2
  67. package/dist/types/puppeteer-agent-launcher.d.ts +1 -1
  68. package/dist/types/puppeteer.d.ts +2 -2
  69. package/dist/types/utils.d.ts +1 -1
  70. package/dist/types/yaml.d.ts +1 -1
  71. package/package.json +18 -54
@@ -344,8 +344,8 @@ var ScriptPlayer = class {
344
344
  var import_js_yaml = __toESM(require("js-yaml"));
345
345
 
346
346
  // src/yaml/utils.ts
347
- var import_utils2 = require("misoai-shared/utils");
348
347
  var import_js_yaml2 = __toESM(require("js-yaml"));
348
+ var import_utils2 = require("misoai-shared/utils");
349
349
  function interpolateEnvVars(content) {
350
350
  return content.replace(/\$\{([^}]+)\}/g, (_, envVar) => {
351
351
  const value = process.env[envVar.trim()];
@@ -491,13 +491,13 @@ function paramStr(task) {
491
491
  }
492
492
 
493
493
  // src/common/utils.ts
494
+ var import_dayjs = __toESM(require("dayjs"));
494
495
  var import_ai_model = require("misoai-core/ai-model");
495
496
  var import_utils3 = require("misoai-core/utils");
496
497
  var import_env = require("misoai-shared/env");
497
498
  var import_extractor = require("misoai-shared/extractor");
498
499
  var import_img = require("misoai-shared/img");
499
500
  var import_utils4 = require("misoai-shared/utils");
500
- var import_dayjs = __toESM(require("dayjs"));
501
501
 
502
502
  // src/web-element.ts
503
503
  var WebElementInfo = class {
@@ -666,8 +666,12 @@ var WorkflowMemory = class {
666
666
  const workflow = this.workflows.get(workflowId) || this.createEmptyWorkflowData(workflowId);
667
667
  workflow.memory = [...memory];
668
668
  workflow.metadata.totalSteps = workflow.steps.length;
669
- workflow.metadata.completedSteps = workflow.steps.filter((s) => s.status === "completed").length;
670
- workflow.metadata.failedSteps = workflow.steps.filter((s) => s.status === "failed").length;
669
+ workflow.metadata.completedSteps = workflow.steps.filter(
670
+ (s) => s.status === "completed"
671
+ ).length;
672
+ workflow.metadata.failedSteps = workflow.steps.filter(
673
+ (s) => s.status === "failed"
674
+ ).length;
671
675
  this.workflows.set(workflowId, workflow);
672
676
  this.enforceRetentionPolicy();
673
677
  }
@@ -678,7 +682,9 @@ var WorkflowMemory = class {
678
682
  const workflow = this.workflows.get(workflowId) || this.createEmptyWorkflowData(workflowId);
679
683
  workflow.context = { ...workflow.context, ...context };
680
684
  if (context.currentStep) {
681
- const existingStep = workflow.steps.find((s) => s.stepName === context.currentStep);
685
+ const existingStep = workflow.steps.find(
686
+ (s) => s.stepName === context.currentStep
687
+ );
682
688
  if (!existingStep) {
683
689
  workflow.steps.push({
684
690
  stepId: `step_${workflow.steps.length + 1}`,
@@ -723,7 +729,9 @@ var WorkflowMemory = class {
723
729
  enforceRetentionPolicy() {
724
730
  const maxWorkflows = 10;
725
731
  if (this.workflows.size > maxWorkflows) {
726
- const sortedWorkflows = Array.from(this.workflows.entries()).sort(([, a], [, b]) => (b.metadata.endTime || b.metadata.startTime) - (a.metadata.endTime || a.metadata.startTime));
732
+ const sortedWorkflows = Array.from(this.workflows.entries()).sort(
733
+ ([, a], [, b]) => (b.metadata.endTime || b.metadata.startTime) - (a.metadata.endTime || a.metadata.startTime)
734
+ );
727
735
  const toDelete = sortedWorkflows.slice(maxWorkflows);
728
736
  toDelete.forEach(([workflowId]) => this.workflows.delete(workflowId));
729
737
  }
@@ -1290,6 +1298,7 @@ var PageTaskExecutor = class {
1290
1298
  actions: [],
1291
1299
  more_actions_needed_by_instruction: false,
1292
1300
  log: "",
1301
+ summary: "Loaded YAML workflow configuration",
1293
1302
  yamlString
1294
1303
  },
1295
1304
  cache: {
@@ -1391,6 +1400,7 @@ var PageTaskExecutor = class {
1391
1400
  actions: finalActions,
1392
1401
  more_actions_needed_by_instruction,
1393
1402
  log: log2,
1403
+ summary: planResult.summary || "Generated action plan from user instruction",
1394
1404
  yamlFlow: planResult.yamlFlow
1395
1405
  },
1396
1406
  cache: {
@@ -1446,6 +1456,7 @@ var PageTaskExecutor = class {
1446
1456
  actionType: actions[0].type,
1447
1457
  more_actions_needed_by_instruction: true,
1448
1458
  log: "",
1459
+ summary: action_summary || "Generated VLM action plan",
1449
1460
  yamlFlow: planResult.yamlFlow
1450
1461
  },
1451
1462
  cache: {
@@ -1462,7 +1473,9 @@ var PageTaskExecutor = class {
1462
1473
  */
1463
1474
  getPersistentExecutor() {
1464
1475
  if (!this.persistentExecutor || this.persistentExecutor.status === "error") {
1465
- const previousMemory = this.workflowMemory.getWorkflowMemory(this.sessionContext.workflowId);
1476
+ const previousMemory = this.workflowMemory.getWorkflowMemory(
1477
+ this.sessionContext.workflowId
1478
+ );
1466
1479
  this.persistentExecutor = new import_misoai_core.Executor("Persistent Task Executor", {
1467
1480
  onTaskStart: this.onTaskStartCallback,
1468
1481
  initialMemory: previousMemory
@@ -1491,7 +1504,9 @@ var PageTaskExecutor = class {
1491
1504
  if (this.persistentExecutor) {
1492
1505
  this.persistentExecutor.clearMemory();
1493
1506
  }
1494
- this.workflowMemory.clearWorkflow(this.sessionContext.workflowId || "default");
1507
+ this.workflowMemory.clearWorkflow(
1508
+ this.sessionContext.workflowId || "default"
1509
+ );
1495
1510
  }
1496
1511
  /**
1497
1512
  * Mevcut hafızayı döndürür
@@ -1503,7 +1518,9 @@ var PageTaskExecutor = class {
1503
1518
  * İş akışı hafızasını döndürür
1504
1519
  */
1505
1520
  getWorkflowMemory() {
1506
- return this.workflowMemory.getWorkflowData(this.sessionContext.workflowId || "default");
1521
+ return this.workflowMemory.getWorkflowData(
1522
+ this.sessionContext.workflowId || "default"
1523
+ );
1507
1524
  }
1508
1525
  /**
1509
1526
  * Hafıza istatistiklerini döndürür
@@ -1511,7 +1528,13 @@ var PageTaskExecutor = class {
1511
1528
  getMemoryStats() {
1512
1529
  return this.persistentExecutor?.getMemoryStats() || {
1513
1530
  totalItems: 0,
1514
- analytics: { totalTasks: 0, memoryHits: 0, memoryMisses: 0, averageMemorySize: 0, memoryEffectiveness: 0 },
1531
+ analytics: {
1532
+ totalTasks: 0,
1533
+ memoryHits: 0,
1534
+ memoryMisses: 0,
1535
+ averageMemorySize: 0,
1536
+ memoryEffectiveness: 0
1537
+ },
1515
1538
  config: this.memoryConfig
1516
1539
  };
1517
1540
  }
@@ -1547,11 +1570,14 @@ var PageTaskExecutor = class {
1547
1570
  let taskExecutor;
1548
1571
  if (useMemory) {
1549
1572
  taskExecutor = this.getPersistentExecutor();
1550
- this.workflowMemory.updateWorkflowContext({
1551
- currentStep: title,
1552
- pageInfo: this.sessionContext.pageInfo,
1553
- timestamp: Date.now()
1554
- }, this.sessionContext.workflowId || "default");
1573
+ this.workflowMemory.updateWorkflowContext(
1574
+ {
1575
+ currentStep: title,
1576
+ pageInfo: this.sessionContext.pageInfo,
1577
+ timestamp: Date.now()
1578
+ },
1579
+ this.sessionContext.workflowId || "default"
1580
+ );
1555
1581
  } else {
1556
1582
  taskExecutor = new import_misoai_core.Executor(title, {
1557
1583
  onTaskStart: this.onTaskStartCallback
@@ -1917,14 +1943,19 @@ var PageTaskExecutor = class {
1917
1943
  */
1918
1944
  addToMemory(memoryItem) {
1919
1945
  if (!this.persistentExecutor || this.persistentExecutor.status === "error") {
1920
- const previousMemory = this.workflowMemory.getWorkflowMemory(this.sessionContext.workflowId);
1946
+ const previousMemory = this.workflowMemory.getWorkflowMemory(
1947
+ this.sessionContext.workflowId
1948
+ );
1921
1949
  this.persistentExecutor = new import_misoai_core.Executor("Persistent Task Executor", {
1922
1950
  onTaskStart: this.onTaskStartCallback,
1923
1951
  initialMemory: previousMemory
1924
1952
  });
1925
1953
  }
1926
1954
  this.persistentExecutor.memoryStore?.add(memoryItem);
1927
- this.persistentExecutor.memoryAnalytics?.recordMemoryOperation("add", memoryItem);
1955
+ this.persistentExecutor.memoryAnalytics?.recordMemoryOperation(
1956
+ "add",
1957
+ memoryItem
1958
+ );
1928
1959
  }
1929
1960
  };
1930
1961
 
@@ -2013,14 +2044,14 @@ function buildPlans(type, locateParam, param) {
2013
2044
  var import_node_assert = __toESM(require("assert"));
2014
2045
  var import_node_fs2 = require("fs");
2015
2046
  var import_node_path2 = require("path");
2047
+ var import_js_yaml3 = __toESM(require("js-yaml"));
2016
2048
  var import_common2 = require("misoai-shared/common");
2017
2049
  var import_logger3 = require("misoai-shared/logger");
2018
2050
  var import_utils9 = require("misoai-shared/utils");
2019
- var import_js_yaml3 = __toESM(require("js-yaml"));
2020
2051
  var import_semver = __toESM(require("semver"));
2021
2052
 
2022
2053
  // package.json
2023
- var version = "1.6.0";
2054
+ var version = "1.6.2";
2024
2055
 
2025
2056
  // src/common/task-cache.ts
2026
2057
  var debug3 = (0, import_logger3.getDebug)("cache");
@@ -2315,22 +2346,28 @@ var PageAgent = class {
2315
2346
  const allThoughts = executor.tasks.filter((task) => task.thought).map((task) => task.thought);
2316
2347
  const allLocates = executor.tasks.filter((task) => task.locate).map((task) => task.locate);
2317
2348
  const allPlans = executor.tasks.filter((task) => task.param?.plans).map((task) => task.param?.plans);
2318
- const planningTasks = executor.tasks.filter((task) => task.type === "Planning");
2319
- const insightTasks = executor.tasks.filter((task) => task.type === "Insight");
2349
+ const planningTasks = executor.tasks.filter(
2350
+ (task) => task.type === "Planning"
2351
+ );
2352
+ const insightTasks = executor.tasks.filter(
2353
+ (task) => task.type === "Insight"
2354
+ );
2320
2355
  const actionTasks = executor.tasks.filter((task) => task.type === "Action");
2321
2356
  const planning = planningTasks.length > 0 ? {
2322
2357
  type: "Planning",
2323
- description: `Planning for task execution`,
2358
+ description: "Planning for task execution",
2324
2359
  steps: planningTasks.map((task) => task.thought || "Planning step")
2325
2360
  } : void 0;
2326
2361
  const insight = insightTasks.length > 0 ? {
2327
2362
  type: "Insight",
2328
- description: `Insight for task execution`,
2329
- elements: insightTasks.map((task) => task.thought || "Insight element")
2363
+ description: "Insight for task execution",
2364
+ elements: insightTasks.map(
2365
+ (task) => task.thought || "Insight element"
2366
+ )
2330
2367
  } : void 0;
2331
2368
  const action = actionTasks.length > 0 ? {
2332
2369
  type: "Action",
2333
- description: `Action for task execution`,
2370
+ description: "Action for task execution",
2334
2371
  result: lastTask?.output
2335
2372
  } : void 0;
2336
2373
  const actionDetails = executor.tasks.map((task) => ({
@@ -2664,7 +2701,10 @@ ${memoryContext}` : void 0;
2664
2701
  }
2665
2702
  const memoryContext = this.getMemoryAsContext();
2666
2703
  const assertionWithContext = currentUrl ? `For the page at URL "${currentUrl}", ${assertion}` : assertion;
2667
- const { output, executor } = await this.taskExecutor.assert(assertionWithContext, memoryContext);
2704
+ const { output, executor } = await this.taskExecutor.assert(
2705
+ assertionWithContext,
2706
+ memoryContext
2707
+ );
2668
2708
  const metadata = this.afterTaskRunning(executor, true);
2669
2709
  if (output && opt?.keepRawResponse) {
2670
2710
  return {
@@ -2703,7 +2743,10 @@ A complex CAPTCHA typically has one or more of these characteristics:
2703
2743
  Return only "complex" or "simple" based on your analysis.
2704
2744
  `;
2705
2745
  const complexityMsgs = [
2706
- { role: "system", content: "You are an AI assistant that analyzes screenshots to determine CAPTCHA complexity." },
2746
+ {
2747
+ role: "system",
2748
+ content: "You are an AI assistant that analyzes screenshots to determine CAPTCHA complexity."
2749
+ },
2707
2750
  {
2708
2751
  role: "user",
2709
2752
  content: [
@@ -2727,7 +2770,12 @@ Return only "complex" or "simple" based on your analysis.
2727
2770
  );
2728
2771
  const responseText = typeof complexityResult.content === "string" ? complexityResult.content.toLowerCase() : JSON.stringify(complexityResult.content).toLowerCase();
2729
2772
  shouldUseDeepThink = responseText.includes("complex");
2730
- debug4("CAPTCHA complexity analysis:", responseText, "Using deep think:", shouldUseDeepThink);
2773
+ debug4(
2774
+ "CAPTCHA complexity analysis:",
2775
+ responseText,
2776
+ "Using deep think:",
2777
+ shouldUseDeepThink
2778
+ );
2731
2779
  } catch (error) {
2732
2780
  debug4("Failed to analyze CAPTCHA complexity:", error);
2733
2781
  }
@@ -2744,7 +2792,9 @@ Return only "complex" or "simple" based on your analysis.
2744
2792
  await this.aiTap(action.target, { deepThink: shouldUseDeepThink });
2745
2793
  } else if (action.type === "input" && action.value) {
2746
2794
  if (action.target) {
2747
- await this.aiInput(action.value, action.target, { deepThink: shouldUseDeepThink });
2795
+ await this.aiInput(action.value, action.target, {
2796
+ deepThink: shouldUseDeepThink
2797
+ });
2748
2798
  }
2749
2799
  } else if (action.type === "verify" && action.target) {
2750
2800
  await this.aiTap(action.target, { deepThink: shouldUseDeepThink });
@@ -2756,7 +2806,9 @@ Return only "complex" or "simple" based on your analysis.
2756
2806
  if (action.coordinates) {
2757
2807
  const x = action.coordinates[0];
2758
2808
  const y = action.coordinates[1];
2759
- await this.aiTap(`element at coordinates (${x}, ${y})`, { deepThink: shouldUseDeepThink });
2809
+ await this.aiTap(`element at coordinates (${x}, ${y})`, {
2810
+ deepThink: shouldUseDeepThink
2811
+ });
2760
2812
  } else if (action.target) {
2761
2813
  await this.aiTap(action.target, { deepThink: shouldUseDeepThink });
2762
2814
  }
@@ -2908,25 +2960,27 @@ ${errors}`);
2908
2960
  const executionDump = {
2909
2961
  name: screenshotTitle,
2910
2962
  description: content,
2911
- tasks: [{
2912
- type: "Screenshot",
2913
- subType: "log",
2914
- status: "finished",
2915
- executor: null,
2916
- param: {
2917
- title: screenshotTitle,
2918
- content
2919
- },
2920
- output: {
2921
- screenshot
2922
- },
2923
- thought: `Logged screenshot: ${screenshotTitle}`,
2924
- timing: {
2925
- start: Date.now(),
2926
- end: Date.now(),
2927
- cost: 0
2963
+ tasks: [
2964
+ {
2965
+ type: "Screenshot",
2966
+ subType: "log",
2967
+ status: "finished",
2968
+ executor: null,
2969
+ param: {
2970
+ title: screenshotTitle,
2971
+ content
2972
+ },
2973
+ output: {
2974
+ screenshot
2975
+ },
2976
+ thought: `Logged screenshot: ${screenshotTitle}`,
2977
+ timing: {
2978
+ start: Date.now(),
2979
+ end: Date.now(),
2980
+ cost: 0
2981
+ }
2928
2982
  }
2929
- }],
2983
+ ],
2930
2984
  sdkVersion: "1.0.0",
2931
2985
  logTime: Date.now(),
2932
2986
  model_name: "screenshot"
@@ -2978,7 +3032,9 @@ ${errors}`);
2978
3032
  totalTasks: stats.analytics.totalTasks,
2979
3033
  memoryHits: stats.analytics.memoryHits,
2980
3034
  memoryMisses: stats.analytics.memoryMisses,
2981
- memoryEffectiveness: Math.round(stats.analytics.memoryEffectiveness * 100),
3035
+ memoryEffectiveness: Math.round(
3036
+ stats.analytics.memoryEffectiveness * 100
3037
+ ),
2982
3038
  averageMemorySize: Math.round(stats.analytics.averageMemorySize * 100) / 100
2983
3039
  },
2984
3040
  config: stats.config,
@@ -3042,7 +3098,9 @@ ${errors}`);
3042
3098
  calculateSuccessRate(memory) {
3043
3099
  if (memory.length === 0)
3044
3100
  return 0;
3045
- const successCount = memory.filter((item) => item.metadata?.success !== false).length;
3101
+ const successCount = memory.filter(
3102
+ (item) => item.metadata?.success !== false
3103
+ ).length;
3046
3104
  return Math.round(successCount / memory.length * 100);
3047
3105
  }
3048
3106
  calculateAverageExecutionTime(memory) {
@@ -3084,13 +3142,236 @@ var import_extractor2 = require("misoai-shared/extractor");
3084
3142
  var import_fs = require("misoai-shared/fs");
3085
3143
  var import_logger5 = require("misoai-shared/logger");
3086
3144
  var import_utils16 = require("misoai-shared/utils");
3145
+
3146
+ // src/common/mouse-utils.ts
3147
+ function generateHumanMousePath(from, to, options = {}) {
3148
+ const {
3149
+ steps = 20,
3150
+ easing = "easeInOut"
3151
+ } = options;
3152
+ if (steps <= 1) {
3153
+ return [to];
3154
+ }
3155
+ const path = [];
3156
+ const controlPoint1 = {
3157
+ x: from.x + (to.x - from.x) * 0.25 + (Math.random() - 0.5) * 50,
3158
+ y: from.y + (to.y - from.y) * 0.25 + (Math.random() - 0.5) * 50
3159
+ };
3160
+ const controlPoint2 = {
3161
+ x: from.x + (to.x - from.x) * 0.75 + (Math.random() - 0.5) * 50,
3162
+ y: from.y + (to.y - from.y) * 0.75 + (Math.random() - 0.5) * 50
3163
+ };
3164
+ for (let i = 0; i <= steps; i++) {
3165
+ const t = i / steps;
3166
+ const easedT = applyEasing(t, easing);
3167
+ const point = calculateBezierPoint(from, controlPoint1, controlPoint2, to, easedT);
3168
+ path.push(point);
3169
+ }
3170
+ return path;
3171
+ }
3172
+ function calculateBezierPoint(p0, p1, p2, p3, t) {
3173
+ const oneMinusT = 1 - t;
3174
+ const oneMinusTSquared = oneMinusT * oneMinusT;
3175
+ const oneMinusTCubed = oneMinusTSquared * oneMinusT;
3176
+ const tSquared = t * t;
3177
+ const tCubed = tSquared * t;
3178
+ return {
3179
+ x: oneMinusTCubed * p0.x + 3 * oneMinusTSquared * t * p1.x + 3 * oneMinusT * tSquared * p2.x + tCubed * p3.x,
3180
+ y: oneMinusTCubed * p0.y + 3 * oneMinusTSquared * t * p1.y + 3 * oneMinusT * tSquared * p2.y + tCubed * p3.y
3181
+ };
3182
+ }
3183
+ function applyEasing(t, easing) {
3184
+ switch (easing) {
3185
+ case "linear":
3186
+ return t;
3187
+ case "easeIn":
3188
+ return t * t;
3189
+ case "easeOut":
3190
+ return 1 - (1 - t) * (1 - t);
3191
+ case "easeInOut":
3192
+ return t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2;
3193
+ default:
3194
+ return t;
3195
+ }
3196
+ }
3197
+ function calculateStepDelay(totalDuration, currentStep, totalSteps) {
3198
+ const baseDelay = totalDuration / totalSteps;
3199
+ const variation = 0.3;
3200
+ const randomFactor = 1 + (Math.random() - 0.5) * variation;
3201
+ return Math.max(1, baseDelay * randomFactor);
3202
+ }
3203
+
3204
+ // src/common/visual-feedback.ts
3205
+ function getMousePointerScript(x, y, options = {}) {
3206
+ const {
3207
+ pointerSize = 20,
3208
+ pointerColor = "#ff4444",
3209
+ trailLength = 5,
3210
+ showTrail = true,
3211
+ animationDuration = 200
3212
+ } = options;
3213
+ return `
3214
+ (() => {
3215
+ // Create or update mouse pointer
3216
+ if (!window.misoaiMousePointer) {
3217
+ const pointer = document.createElement('div');
3218
+ pointer.id = 'misoai-mouse-pointer';
3219
+ pointer.style.cssText = \`
3220
+ position: fixed;
3221
+ width: ${pointerSize}px;
3222
+ height: ${pointerSize}px;
3223
+ background: ${pointerColor};
3224
+ border: 2px solid white;
3225
+ border-radius: 50%;
3226
+ pointer-events: none;
3227
+ z-index: 999999;
3228
+ box-shadow: 0 0 10px rgba(0,0,0,0.3);
3229
+ transition: all ${animationDuration}ms ease-out;
3230
+ transform: translate(-50%, -50%);
3231
+ \`;
3232
+ document.body.appendChild(pointer);
3233
+ window.misoaiMousePointer = pointer;
3234
+
3235
+ // Initialize trail array
3236
+ window.misoaiMouseTrail = [];
3237
+ }
3238
+
3239
+ const pointer = window.misoaiMousePointer;
3240
+ pointer.style.left = ${x}px;
3241
+ pointer.style.top = ${y}px;
3242
+
3243
+ ${showTrail ? getTrailScript(x, y, trailLength, pointerColor) : ""}
3244
+
3245
+ // Auto-hide after 3 seconds of inactivity
3246
+ clearTimeout(window.misoaiMouseTimeout);
3247
+ pointer.style.opacity = '1';
3248
+ window.misoaiMouseTimeout = setTimeout(() => {
3249
+ if (pointer) pointer.style.opacity = '0.3';
3250
+ }, 3000);
3251
+ })();
3252
+ `;
3253
+ }
3254
+ function getTrailScript(x, y, trailLength, color) {
3255
+ return `
3256
+ // Add current position to trail
3257
+ window.misoaiMouseTrail.push({ x: ${x}, y: ${y}, timestamp: Date.now() });
3258
+
3259
+ // Keep only recent trail points
3260
+ if (window.misoaiMouseTrail.length > ${trailLength}) {
3261
+ window.misoaiMouseTrail.shift();
3262
+ }
3263
+
3264
+ // Remove old trail elements
3265
+ document.querySelectorAll('.misoai-mouse-trail').forEach(el => el.remove());
3266
+
3267
+ // Create new trail elements
3268
+ window.misoaiMouseTrail.forEach((point, index) => {
3269
+ if (index === window.misoaiMouseTrail.length - 1) return; // Skip current position
3270
+
3271
+ const trailElement = document.createElement('div');
3272
+ trailElement.className = 'misoai-mouse-trail';
3273
+ const opacity = (index + 1) / window.misoaiMouseTrail.length * 0.6;
3274
+ const size = 8 + (index + 1) / window.misoaiMouseTrail.length * 8;
3275
+
3276
+ trailElement.style.cssText = \`
3277
+ position: fixed;
3278
+ width: \${size}px;
3279
+ height: \${size}px;
3280
+ background: ${color};
3281
+ border-radius: 50%;
3282
+ pointer-events: none;
3283
+ z-index: 999998;
3284
+ opacity: \${opacity};
3285
+ transform: translate(-50%, -50%);
3286
+ left: \${point.x}px;
3287
+ top: \${point.y}px;
3288
+ \`;
3289
+
3290
+ document.body.appendChild(trailElement);
3291
+
3292
+ // Auto-remove trail element after animation
3293
+ setTimeout(() => {
3294
+ if (trailElement.parentNode) {
3295
+ trailElement.parentNode.removeChild(trailElement);
3296
+ }
3297
+ }, 1000);
3298
+ });
3299
+ `;
3300
+ }
3301
+ function getClickAnimationScript(x, y) {
3302
+ return `
3303
+ (() => {
3304
+ const clickRipple = document.createElement('div');
3305
+ clickRipple.style.cssText = \`
3306
+ position: fixed;
3307
+ left: ${x}px;
3308
+ top: ${y}px;
3309
+ width: 0;
3310
+ height: 0;
3311
+ border: 2px solid #ff4444;
3312
+ border-radius: 50%;
3313
+ pointer-events: none;
3314
+ z-index: 999999;
3315
+ transform: translate(-50%, -50%);
3316
+ animation: misoai-click-ripple 0.6s ease-out forwards;
3317
+ \`;
3318
+
3319
+ // Add CSS animation if not exists
3320
+ if (!document.getElementById('misoai-click-styles')) {
3321
+ const style = document.createElement('style');
3322
+ style.id = 'misoai-click-styles';
3323
+ style.textContent = \`
3324
+ @keyframes misoai-click-ripple {
3325
+ 0% {
3326
+ width: 0;
3327
+ height: 0;
3328
+ opacity: 1;
3329
+ }
3330
+ 100% {
3331
+ width: 40px;
3332
+ height: 40px;
3333
+ opacity: 0;
3334
+ }
3335
+ }
3336
+ \`;
3337
+ document.head.appendChild(style);
3338
+ }
3339
+
3340
+ document.body.appendChild(clickRipple);
3341
+
3342
+ // Remove after animation
3343
+ setTimeout(() => {
3344
+ if (clickRipple.parentNode) {
3345
+ clickRipple.parentNode.removeChild(clickRipple);
3346
+ }
3347
+ }, 600);
3348
+ })();
3349
+ `;
3350
+ }
3351
+
3352
+ // src/puppeteer/base-page.ts
3087
3353
  var debugPage = (0, import_logger5.getDebug)("web:page");
3088
3354
  var Page = class {
3089
3355
  constructor(underlyingPage, pageType, opts) {
3356
+ this.currentMousePosition = { x: 0, y: 0 };
3357
+ this.mouseMovementOptions = {
3358
+ steps: 15,
3359
+ duration: 300,
3360
+ easing: "easeInOut",
3361
+ showVisualFeedback: true
3362
+ };
3363
+ this.visualFeedbackOptions = {
3364
+ pointerSize: 16,
3365
+ pointerColor: "#ff4444",
3366
+ trailLength: 4,
3367
+ showTrail: true,
3368
+ animationDuration: 150
3369
+ };
3090
3370
  this.everMoved = false;
3091
3371
  this.underlyingPage = underlyingPage;
3092
3372
  this.pageType = pageType;
3093
3373
  this.waitForNavigationTimeout = opts?.waitForNavigationTimeout ?? import_constants3.DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT;
3374
+ this.initializeMousePosition();
3094
3375
  }
3095
3376
  async evaluate(pageFunction, arg) {
3096
3377
  let result;
@@ -3109,9 +3390,76 @@ var Page = class {
3109
3390
  debugPage("evaluate function end");
3110
3391
  return result;
3111
3392
  }
3393
+ /**
3394
+ * Initialize mouse position to center of viewport
3395
+ */
3396
+ async initializeMousePosition() {
3397
+ try {
3398
+ const size = await this.size();
3399
+ this.currentMousePosition = {
3400
+ x: Math.floor(size.width / 2),
3401
+ y: Math.floor(size.height / 2)
3402
+ };
3403
+ } catch (error) {
3404
+ this.currentMousePosition = { x: 400, y: 300 };
3405
+ }
3406
+ }
3112
3407
  async evaluateJavaScript(script) {
3113
3408
  return this.evaluate(script);
3114
3409
  }
3410
+ /**
3411
+ * Show visual feedback for mouse pointer
3412
+ */
3413
+ async showMousePointer(x, y) {
3414
+ if (!this.mouseMovementOptions.showVisualFeedback)
3415
+ return;
3416
+ const script = getMousePointerScript(x, y, this.visualFeedbackOptions);
3417
+ try {
3418
+ await this.evaluate(script);
3419
+ } catch (error) {
3420
+ debugPage("Visual feedback error:", error);
3421
+ }
3422
+ }
3423
+ /**
3424
+ * Show click animation
3425
+ */
3426
+ async showClickAnimation(x, y) {
3427
+ if (!this.mouseMovementOptions.showVisualFeedback)
3428
+ return;
3429
+ const script = getClickAnimationScript(x, y);
3430
+ try {
3431
+ await this.evaluate(script);
3432
+ } catch (error) {
3433
+ debugPage("Click animation error:", error);
3434
+ }
3435
+ }
3436
+ /**
3437
+ * Move mouse with human-like movement and visual feedback
3438
+ */
3439
+ async moveMouseHumanLike(toX, toY, options) {
3440
+ const moveOptions = { ...this.mouseMovementOptions, ...options };
3441
+ const path = generateHumanMousePath(
3442
+ this.currentMousePosition,
3443
+ { x: toX, y: toY },
3444
+ moveOptions
3445
+ );
3446
+ for (let i = 0; i < path.length; i++) {
3447
+ const point = path[i];
3448
+ if (moveOptions.showVisualFeedback) {
3449
+ await this.showMousePointer(point.x, point.y);
3450
+ }
3451
+ await this.underlyingPage.mouse.move(point.x, point.y);
3452
+ this.currentMousePosition = point;
3453
+ if (i < path.length - 1) {
3454
+ const delay = calculateStepDelay(
3455
+ moveOptions.duration || 300,
3456
+ i,
3457
+ path.length
3458
+ );
3459
+ await (0, import_utils15.sleep)(delay);
3460
+ }
3461
+ }
3462
+ }
3115
3463
  async waitForNavigation() {
3116
3464
  if (this.pageType === "puppeteer" || this.pageType === "playwright") {
3117
3465
  debugPage("waitForNavigation begin");
@@ -3201,7 +3549,8 @@ var Page = class {
3201
3549
  return {
3202
3550
  click: async (x, y, options) => {
3203
3551
  await this.mouse.move(x, y);
3204
- this.underlyingPage.mouse.click(x, y, {
3552
+ await this.showClickAnimation(x, y);
3553
+ await this.underlyingPage.mouse.click(x, y, {
3205
3554
  button: options?.button || "left",
3206
3555
  count: options?.count || 1
3207
3556
  });
@@ -3221,27 +3570,23 @@ var Page = class {
3221
3570
  },
3222
3571
  move: async (x, y) => {
3223
3572
  this.everMoved = true;
3224
- return this.underlyingPage.mouse.move(x, y);
3573
+ await this.moveMouseHumanLike(x, y);
3574
+ return Promise.resolve();
3225
3575
  },
3226
3576
  drag: async (from, to) => {
3227
3577
  if (this.pageType === "puppeteer") {
3228
- await this.underlyingPage.mouse.drag(
3229
- {
3230
- x: from.x,
3231
- y: from.y
3232
- },
3233
- {
3234
- x: to.x,
3235
- y: to.y
3236
- }
3237
- );
3578
+ await this.mouse.move(from.x, from.y);
3579
+ await this.underlyingPage.mouse.down();
3580
+ await this.moveMouseHumanLike(to.x, to.y, {
3581
+ duration: 500,
3582
+ // Slower for drag operations
3583
+ steps: 25
3584
+ });
3585
+ await this.underlyingPage.mouse.up();
3238
3586
  } else if (this.pageType === "playwright") {
3239
- await this.underlyingPage.mouse.move(
3240
- from.x,
3241
- from.y
3242
- );
3587
+ await this.mouse.move(from.x, from.y);
3243
3588
  await this.underlyingPage.mouse.down();
3244
- await this.underlyingPage.mouse.move(to.x, to.y);
3589
+ await this.mouse.move(to.x, to.y);
3245
3590
  await this.underlyingPage.mouse.up();
3246
3591
  }
3247
3592
  }
@@ -3304,6 +3649,18 @@ var Page = class {
3304
3649
  await this.mouse.move(targetX, targetY);
3305
3650
  }
3306
3651
  }
3652
+ /**
3653
+ * Configure mouse movement behavior
3654
+ */
3655
+ configureMouseMovement(options) {
3656
+ this.mouseMovementOptions = { ...this.mouseMovementOptions, ...options };
3657
+ }
3658
+ /**
3659
+ * Configure visual feedback
3660
+ */
3661
+ configureVisualFeedback(options) {
3662
+ this.visualFeedbackOptions = { ...this.visualFeedbackOptions, ...options };
3663
+ }
3307
3664
  async scrollUntilTop(startingPoint) {
3308
3665
  await this.moveToPointBeforeScroll(startingPoint);
3309
3666
  return this.mouse.wheel(0, -9999999);