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
@@ -351,8 +351,8 @@ var ScriptPlayer = class {
351
351
  var import_js_yaml = __toESM(require("js-yaml"));
352
352
 
353
353
  // src/yaml/utils.ts
354
- var import_utils2 = require("misoai-shared/utils");
355
354
  var import_js_yaml2 = __toESM(require("js-yaml"));
355
+ var import_utils2 = require("misoai-shared/utils");
356
356
  function interpolateEnvVars(content) {
357
357
  return content.replace(/\$\{([^}]+)\}/g, (_, envVar) => {
358
358
  const value = process.env[envVar.trim()];
@@ -498,13 +498,13 @@ function paramStr(task) {
498
498
  }
499
499
 
500
500
  // src/common/utils.ts
501
+ var import_dayjs = __toESM(require("dayjs"));
501
502
  var import_ai_model = require("misoai-core/ai-model");
502
503
  var import_utils3 = require("misoai-core/utils");
503
504
  var import_env = require("misoai-shared/env");
504
505
  var import_extractor = require("misoai-shared/extractor");
505
506
  var import_img = require("misoai-shared/img");
506
507
  var import_utils4 = require("misoai-shared/utils");
507
- var import_dayjs = __toESM(require("dayjs"));
508
508
 
509
509
  // src/web-element.ts
510
510
  var WebElementInfo = class {
@@ -673,8 +673,12 @@ var WorkflowMemory = class {
673
673
  const workflow = this.workflows.get(workflowId) || this.createEmptyWorkflowData(workflowId);
674
674
  workflow.memory = [...memory];
675
675
  workflow.metadata.totalSteps = workflow.steps.length;
676
- workflow.metadata.completedSteps = workflow.steps.filter((s) => s.status === "completed").length;
677
- workflow.metadata.failedSteps = workflow.steps.filter((s) => s.status === "failed").length;
676
+ workflow.metadata.completedSteps = workflow.steps.filter(
677
+ (s) => s.status === "completed"
678
+ ).length;
679
+ workflow.metadata.failedSteps = workflow.steps.filter(
680
+ (s) => s.status === "failed"
681
+ ).length;
678
682
  this.workflows.set(workflowId, workflow);
679
683
  this.enforceRetentionPolicy();
680
684
  }
@@ -685,7 +689,9 @@ var WorkflowMemory = class {
685
689
  const workflow = this.workflows.get(workflowId) || this.createEmptyWorkflowData(workflowId);
686
690
  workflow.context = { ...workflow.context, ...context };
687
691
  if (context.currentStep) {
688
- const existingStep = workflow.steps.find((s) => s.stepName === context.currentStep);
692
+ const existingStep = workflow.steps.find(
693
+ (s) => s.stepName === context.currentStep
694
+ );
689
695
  if (!existingStep) {
690
696
  workflow.steps.push({
691
697
  stepId: `step_${workflow.steps.length + 1}`,
@@ -730,7 +736,9 @@ var WorkflowMemory = class {
730
736
  enforceRetentionPolicy() {
731
737
  const maxWorkflows = 10;
732
738
  if (this.workflows.size > maxWorkflows) {
733
- const sortedWorkflows = Array.from(this.workflows.entries()).sort(([, a], [, b]) => (b.metadata.endTime || b.metadata.startTime) - (a.metadata.endTime || a.metadata.startTime));
739
+ const sortedWorkflows = Array.from(this.workflows.entries()).sort(
740
+ ([, a], [, b]) => (b.metadata.endTime || b.metadata.startTime) - (a.metadata.endTime || a.metadata.startTime)
741
+ );
734
742
  const toDelete = sortedWorkflows.slice(maxWorkflows);
735
743
  toDelete.forEach(([workflowId]) => this.workflows.delete(workflowId));
736
744
  }
@@ -1297,6 +1305,7 @@ var PageTaskExecutor = class {
1297
1305
  actions: [],
1298
1306
  more_actions_needed_by_instruction: false,
1299
1307
  log: "",
1308
+ summary: "Loaded YAML workflow configuration",
1300
1309
  yamlString
1301
1310
  },
1302
1311
  cache: {
@@ -1398,6 +1407,7 @@ var PageTaskExecutor = class {
1398
1407
  actions: finalActions,
1399
1408
  more_actions_needed_by_instruction,
1400
1409
  log: log2,
1410
+ summary: planResult.summary || "Generated action plan from user instruction",
1401
1411
  yamlFlow: planResult.yamlFlow
1402
1412
  },
1403
1413
  cache: {
@@ -1453,6 +1463,7 @@ var PageTaskExecutor = class {
1453
1463
  actionType: actions[0].type,
1454
1464
  more_actions_needed_by_instruction: true,
1455
1465
  log: "",
1466
+ summary: action_summary || "Generated VLM action plan",
1456
1467
  yamlFlow: planResult.yamlFlow
1457
1468
  },
1458
1469
  cache: {
@@ -1469,7 +1480,9 @@ var PageTaskExecutor = class {
1469
1480
  */
1470
1481
  getPersistentExecutor() {
1471
1482
  if (!this.persistentExecutor || this.persistentExecutor.status === "error") {
1472
- const previousMemory = this.workflowMemory.getWorkflowMemory(this.sessionContext.workflowId);
1483
+ const previousMemory = this.workflowMemory.getWorkflowMemory(
1484
+ this.sessionContext.workflowId
1485
+ );
1473
1486
  this.persistentExecutor = new import_misoai_core.Executor("Persistent Task Executor", {
1474
1487
  onTaskStart: this.onTaskStartCallback,
1475
1488
  initialMemory: previousMemory
@@ -1498,7 +1511,9 @@ var PageTaskExecutor = class {
1498
1511
  if (this.persistentExecutor) {
1499
1512
  this.persistentExecutor.clearMemory();
1500
1513
  }
1501
- this.workflowMemory.clearWorkflow(this.sessionContext.workflowId || "default");
1514
+ this.workflowMemory.clearWorkflow(
1515
+ this.sessionContext.workflowId || "default"
1516
+ );
1502
1517
  }
1503
1518
  /**
1504
1519
  * Mevcut hafızayı döndürür
@@ -1510,7 +1525,9 @@ var PageTaskExecutor = class {
1510
1525
  * İş akışı hafızasını döndürür
1511
1526
  */
1512
1527
  getWorkflowMemory() {
1513
- return this.workflowMemory.getWorkflowData(this.sessionContext.workflowId || "default");
1528
+ return this.workflowMemory.getWorkflowData(
1529
+ this.sessionContext.workflowId || "default"
1530
+ );
1514
1531
  }
1515
1532
  /**
1516
1533
  * Hafıza istatistiklerini döndürür
@@ -1518,7 +1535,13 @@ var PageTaskExecutor = class {
1518
1535
  getMemoryStats() {
1519
1536
  return this.persistentExecutor?.getMemoryStats() || {
1520
1537
  totalItems: 0,
1521
- analytics: { totalTasks: 0, memoryHits: 0, memoryMisses: 0, averageMemorySize: 0, memoryEffectiveness: 0 },
1538
+ analytics: {
1539
+ totalTasks: 0,
1540
+ memoryHits: 0,
1541
+ memoryMisses: 0,
1542
+ averageMemorySize: 0,
1543
+ memoryEffectiveness: 0
1544
+ },
1522
1545
  config: this.memoryConfig
1523
1546
  };
1524
1547
  }
@@ -1554,11 +1577,14 @@ var PageTaskExecutor = class {
1554
1577
  let taskExecutor;
1555
1578
  if (useMemory) {
1556
1579
  taskExecutor = this.getPersistentExecutor();
1557
- this.workflowMemory.updateWorkflowContext({
1558
- currentStep: title,
1559
- pageInfo: this.sessionContext.pageInfo,
1560
- timestamp: Date.now()
1561
- }, this.sessionContext.workflowId || "default");
1580
+ this.workflowMemory.updateWorkflowContext(
1581
+ {
1582
+ currentStep: title,
1583
+ pageInfo: this.sessionContext.pageInfo,
1584
+ timestamp: Date.now()
1585
+ },
1586
+ this.sessionContext.workflowId || "default"
1587
+ );
1562
1588
  } else {
1563
1589
  taskExecutor = new import_misoai_core.Executor(title, {
1564
1590
  onTaskStart: this.onTaskStartCallback
@@ -1924,14 +1950,19 @@ var PageTaskExecutor = class {
1924
1950
  */
1925
1951
  addToMemory(memoryItem) {
1926
1952
  if (!this.persistentExecutor || this.persistentExecutor.status === "error") {
1927
- const previousMemory = this.workflowMemory.getWorkflowMemory(this.sessionContext.workflowId);
1953
+ const previousMemory = this.workflowMemory.getWorkflowMemory(
1954
+ this.sessionContext.workflowId
1955
+ );
1928
1956
  this.persistentExecutor = new import_misoai_core.Executor("Persistent Task Executor", {
1929
1957
  onTaskStart: this.onTaskStartCallback,
1930
1958
  initialMemory: previousMemory
1931
1959
  });
1932
1960
  }
1933
1961
  this.persistentExecutor.memoryStore?.add(memoryItem);
1934
- this.persistentExecutor.memoryAnalytics?.recordMemoryOperation("add", memoryItem);
1962
+ this.persistentExecutor.memoryAnalytics?.recordMemoryOperation(
1963
+ "add",
1964
+ memoryItem
1965
+ );
1935
1966
  }
1936
1967
  };
1937
1968
 
@@ -2020,14 +2051,14 @@ function buildPlans(type, locateParam, param) {
2020
2051
  var import_node_assert = __toESM(require("assert"));
2021
2052
  var import_node_fs2 = require("fs");
2022
2053
  var import_node_path2 = require("path");
2054
+ var import_js_yaml3 = __toESM(require("js-yaml"));
2023
2055
  var import_common2 = require("misoai-shared/common");
2024
2056
  var import_logger3 = require("misoai-shared/logger");
2025
2057
  var import_utils9 = require("misoai-shared/utils");
2026
- var import_js_yaml3 = __toESM(require("js-yaml"));
2027
2058
  var import_semver = __toESM(require("semver"));
2028
2059
 
2029
2060
  // package.json
2030
- var version = "1.6.0";
2061
+ var version = "1.6.2";
2031
2062
 
2032
2063
  // src/common/task-cache.ts
2033
2064
  var debug3 = (0, import_logger3.getDebug)("cache");
@@ -2322,22 +2353,28 @@ var PageAgent = class {
2322
2353
  const allThoughts = executor.tasks.filter((task) => task.thought).map((task) => task.thought);
2323
2354
  const allLocates = executor.tasks.filter((task) => task.locate).map((task) => task.locate);
2324
2355
  const allPlans = executor.tasks.filter((task) => task.param?.plans).map((task) => task.param?.plans);
2325
- const planningTasks = executor.tasks.filter((task) => task.type === "Planning");
2326
- const insightTasks = executor.tasks.filter((task) => task.type === "Insight");
2356
+ const planningTasks = executor.tasks.filter(
2357
+ (task) => task.type === "Planning"
2358
+ );
2359
+ const insightTasks = executor.tasks.filter(
2360
+ (task) => task.type === "Insight"
2361
+ );
2327
2362
  const actionTasks = executor.tasks.filter((task) => task.type === "Action");
2328
2363
  const planning = planningTasks.length > 0 ? {
2329
2364
  type: "Planning",
2330
- description: `Planning for task execution`,
2365
+ description: "Planning for task execution",
2331
2366
  steps: planningTasks.map((task) => task.thought || "Planning step")
2332
2367
  } : void 0;
2333
2368
  const insight = insightTasks.length > 0 ? {
2334
2369
  type: "Insight",
2335
- description: `Insight for task execution`,
2336
- elements: insightTasks.map((task) => task.thought || "Insight element")
2370
+ description: "Insight for task execution",
2371
+ elements: insightTasks.map(
2372
+ (task) => task.thought || "Insight element"
2373
+ )
2337
2374
  } : void 0;
2338
2375
  const action = actionTasks.length > 0 ? {
2339
2376
  type: "Action",
2340
- description: `Action for task execution`,
2377
+ description: "Action for task execution",
2341
2378
  result: lastTask?.output
2342
2379
  } : void 0;
2343
2380
  const actionDetails = executor.tasks.map((task) => ({
@@ -2671,7 +2708,10 @@ ${memoryContext}` : void 0;
2671
2708
  }
2672
2709
  const memoryContext = this.getMemoryAsContext();
2673
2710
  const assertionWithContext = currentUrl ? `For the page at URL "${currentUrl}", ${assertion}` : assertion;
2674
- const { output, executor } = await this.taskExecutor.assert(assertionWithContext, memoryContext);
2711
+ const { output, executor } = await this.taskExecutor.assert(
2712
+ assertionWithContext,
2713
+ memoryContext
2714
+ );
2675
2715
  const metadata = this.afterTaskRunning(executor, true);
2676
2716
  if (output && opt?.keepRawResponse) {
2677
2717
  return {
@@ -2710,7 +2750,10 @@ A complex CAPTCHA typically has one or more of these characteristics:
2710
2750
  Return only "complex" or "simple" based on your analysis.
2711
2751
  `;
2712
2752
  const complexityMsgs = [
2713
- { role: "system", content: "You are an AI assistant that analyzes screenshots to determine CAPTCHA complexity." },
2753
+ {
2754
+ role: "system",
2755
+ content: "You are an AI assistant that analyzes screenshots to determine CAPTCHA complexity."
2756
+ },
2714
2757
  {
2715
2758
  role: "user",
2716
2759
  content: [
@@ -2734,7 +2777,12 @@ Return only "complex" or "simple" based on your analysis.
2734
2777
  );
2735
2778
  const responseText = typeof complexityResult.content === "string" ? complexityResult.content.toLowerCase() : JSON.stringify(complexityResult.content).toLowerCase();
2736
2779
  shouldUseDeepThink = responseText.includes("complex");
2737
- debug4("CAPTCHA complexity analysis:", responseText, "Using deep think:", shouldUseDeepThink);
2780
+ debug4(
2781
+ "CAPTCHA complexity analysis:",
2782
+ responseText,
2783
+ "Using deep think:",
2784
+ shouldUseDeepThink
2785
+ );
2738
2786
  } catch (error) {
2739
2787
  debug4("Failed to analyze CAPTCHA complexity:", error);
2740
2788
  }
@@ -2751,7 +2799,9 @@ Return only "complex" or "simple" based on your analysis.
2751
2799
  await this.aiTap(action.target, { deepThink: shouldUseDeepThink });
2752
2800
  } else if (action.type === "input" && action.value) {
2753
2801
  if (action.target) {
2754
- await this.aiInput(action.value, action.target, { deepThink: shouldUseDeepThink });
2802
+ await this.aiInput(action.value, action.target, {
2803
+ deepThink: shouldUseDeepThink
2804
+ });
2755
2805
  }
2756
2806
  } else if (action.type === "verify" && action.target) {
2757
2807
  await this.aiTap(action.target, { deepThink: shouldUseDeepThink });
@@ -2763,7 +2813,9 @@ Return only "complex" or "simple" based on your analysis.
2763
2813
  if (action.coordinates) {
2764
2814
  const x = action.coordinates[0];
2765
2815
  const y = action.coordinates[1];
2766
- await this.aiTap(`element at coordinates (${x}, ${y})`, { deepThink: shouldUseDeepThink });
2816
+ await this.aiTap(`element at coordinates (${x}, ${y})`, {
2817
+ deepThink: shouldUseDeepThink
2818
+ });
2767
2819
  } else if (action.target) {
2768
2820
  await this.aiTap(action.target, { deepThink: shouldUseDeepThink });
2769
2821
  }
@@ -2915,25 +2967,27 @@ ${errors}`);
2915
2967
  const executionDump = {
2916
2968
  name: screenshotTitle,
2917
2969
  description: content,
2918
- tasks: [{
2919
- type: "Screenshot",
2920
- subType: "log",
2921
- status: "finished",
2922
- executor: null,
2923
- param: {
2924
- title: screenshotTitle,
2925
- content
2926
- },
2927
- output: {
2928
- screenshot
2929
- },
2930
- thought: `Logged screenshot: ${screenshotTitle}`,
2931
- timing: {
2932
- start: Date.now(),
2933
- end: Date.now(),
2934
- cost: 0
2970
+ tasks: [
2971
+ {
2972
+ type: "Screenshot",
2973
+ subType: "log",
2974
+ status: "finished",
2975
+ executor: null,
2976
+ param: {
2977
+ title: screenshotTitle,
2978
+ content
2979
+ },
2980
+ output: {
2981
+ screenshot
2982
+ },
2983
+ thought: `Logged screenshot: ${screenshotTitle}`,
2984
+ timing: {
2985
+ start: Date.now(),
2986
+ end: Date.now(),
2987
+ cost: 0
2988
+ }
2935
2989
  }
2936
- }],
2990
+ ],
2937
2991
  sdkVersion: "1.0.0",
2938
2992
  logTime: Date.now(),
2939
2993
  model_name: "screenshot"
@@ -2985,7 +3039,9 @@ ${errors}`);
2985
3039
  totalTasks: stats.analytics.totalTasks,
2986
3040
  memoryHits: stats.analytics.memoryHits,
2987
3041
  memoryMisses: stats.analytics.memoryMisses,
2988
- memoryEffectiveness: Math.round(stats.analytics.memoryEffectiveness * 100),
3042
+ memoryEffectiveness: Math.round(
3043
+ stats.analytics.memoryEffectiveness * 100
3044
+ ),
2989
3045
  averageMemorySize: Math.round(stats.analytics.averageMemorySize * 100) / 100
2990
3046
  },
2991
3047
  config: stats.config,
@@ -3049,7 +3105,9 @@ ${errors}`);
3049
3105
  calculateSuccessRate(memory) {
3050
3106
  if (memory.length === 0)
3051
3107
  return 0;
3052
- const successCount = memory.filter((item) => item.metadata?.success !== false).length;
3108
+ const successCount = memory.filter(
3109
+ (item) => item.metadata?.success !== false
3110
+ ).length;
3053
3111
  return Math.round(successCount / memory.length * 100);
3054
3112
  }
3055
3113
  calculateAverageExecutionTime(memory) {
@@ -3091,13 +3149,236 @@ var import_extractor2 = require("misoai-shared/extractor");
3091
3149
  var import_fs = require("misoai-shared/fs");
3092
3150
  var import_logger5 = require("misoai-shared/logger");
3093
3151
  var import_utils16 = require("misoai-shared/utils");
3152
+
3153
+ // src/common/mouse-utils.ts
3154
+ function generateHumanMousePath(from, to, options = {}) {
3155
+ const {
3156
+ steps = 20,
3157
+ easing = "easeInOut"
3158
+ } = options;
3159
+ if (steps <= 1) {
3160
+ return [to];
3161
+ }
3162
+ const path = [];
3163
+ const controlPoint1 = {
3164
+ x: from.x + (to.x - from.x) * 0.25 + (Math.random() - 0.5) * 50,
3165
+ y: from.y + (to.y - from.y) * 0.25 + (Math.random() - 0.5) * 50
3166
+ };
3167
+ const controlPoint2 = {
3168
+ x: from.x + (to.x - from.x) * 0.75 + (Math.random() - 0.5) * 50,
3169
+ y: from.y + (to.y - from.y) * 0.75 + (Math.random() - 0.5) * 50
3170
+ };
3171
+ for (let i = 0; i <= steps; i++) {
3172
+ const t = i / steps;
3173
+ const easedT = applyEasing(t, easing);
3174
+ const point = calculateBezierPoint(from, controlPoint1, controlPoint2, to, easedT);
3175
+ path.push(point);
3176
+ }
3177
+ return path;
3178
+ }
3179
+ function calculateBezierPoint(p0, p1, p2, p3, t) {
3180
+ const oneMinusT = 1 - t;
3181
+ const oneMinusTSquared = oneMinusT * oneMinusT;
3182
+ const oneMinusTCubed = oneMinusTSquared * oneMinusT;
3183
+ const tSquared = t * t;
3184
+ const tCubed = tSquared * t;
3185
+ return {
3186
+ x: oneMinusTCubed * p0.x + 3 * oneMinusTSquared * t * p1.x + 3 * oneMinusT * tSquared * p2.x + tCubed * p3.x,
3187
+ y: oneMinusTCubed * p0.y + 3 * oneMinusTSquared * t * p1.y + 3 * oneMinusT * tSquared * p2.y + tCubed * p3.y
3188
+ };
3189
+ }
3190
+ function applyEasing(t, easing) {
3191
+ switch (easing) {
3192
+ case "linear":
3193
+ return t;
3194
+ case "easeIn":
3195
+ return t * t;
3196
+ case "easeOut":
3197
+ return 1 - (1 - t) * (1 - t);
3198
+ case "easeInOut":
3199
+ return t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2;
3200
+ default:
3201
+ return t;
3202
+ }
3203
+ }
3204
+ function calculateStepDelay(totalDuration, currentStep, totalSteps) {
3205
+ const baseDelay = totalDuration / totalSteps;
3206
+ const variation = 0.3;
3207
+ const randomFactor = 1 + (Math.random() - 0.5) * variation;
3208
+ return Math.max(1, baseDelay * randomFactor);
3209
+ }
3210
+
3211
+ // src/common/visual-feedback.ts
3212
+ function getMousePointerScript(x, y, options = {}) {
3213
+ const {
3214
+ pointerSize = 20,
3215
+ pointerColor = "#ff4444",
3216
+ trailLength = 5,
3217
+ showTrail = true,
3218
+ animationDuration = 200
3219
+ } = options;
3220
+ return `
3221
+ (() => {
3222
+ // Create or update mouse pointer
3223
+ if (!window.misoaiMousePointer) {
3224
+ const pointer = document.createElement('div');
3225
+ pointer.id = 'misoai-mouse-pointer';
3226
+ pointer.style.cssText = \`
3227
+ position: fixed;
3228
+ width: ${pointerSize}px;
3229
+ height: ${pointerSize}px;
3230
+ background: ${pointerColor};
3231
+ border: 2px solid white;
3232
+ border-radius: 50%;
3233
+ pointer-events: none;
3234
+ z-index: 999999;
3235
+ box-shadow: 0 0 10px rgba(0,0,0,0.3);
3236
+ transition: all ${animationDuration}ms ease-out;
3237
+ transform: translate(-50%, -50%);
3238
+ \`;
3239
+ document.body.appendChild(pointer);
3240
+ window.misoaiMousePointer = pointer;
3241
+
3242
+ // Initialize trail array
3243
+ window.misoaiMouseTrail = [];
3244
+ }
3245
+
3246
+ const pointer = window.misoaiMousePointer;
3247
+ pointer.style.left = ${x}px;
3248
+ pointer.style.top = ${y}px;
3249
+
3250
+ ${showTrail ? getTrailScript(x, y, trailLength, pointerColor) : ""}
3251
+
3252
+ // Auto-hide after 3 seconds of inactivity
3253
+ clearTimeout(window.misoaiMouseTimeout);
3254
+ pointer.style.opacity = '1';
3255
+ window.misoaiMouseTimeout = setTimeout(() => {
3256
+ if (pointer) pointer.style.opacity = '0.3';
3257
+ }, 3000);
3258
+ })();
3259
+ `;
3260
+ }
3261
+ function getTrailScript(x, y, trailLength, color) {
3262
+ return `
3263
+ // Add current position to trail
3264
+ window.misoaiMouseTrail.push({ x: ${x}, y: ${y}, timestamp: Date.now() });
3265
+
3266
+ // Keep only recent trail points
3267
+ if (window.misoaiMouseTrail.length > ${trailLength}) {
3268
+ window.misoaiMouseTrail.shift();
3269
+ }
3270
+
3271
+ // Remove old trail elements
3272
+ document.querySelectorAll('.misoai-mouse-trail').forEach(el => el.remove());
3273
+
3274
+ // Create new trail elements
3275
+ window.misoaiMouseTrail.forEach((point, index) => {
3276
+ if (index === window.misoaiMouseTrail.length - 1) return; // Skip current position
3277
+
3278
+ const trailElement = document.createElement('div');
3279
+ trailElement.className = 'misoai-mouse-trail';
3280
+ const opacity = (index + 1) / window.misoaiMouseTrail.length * 0.6;
3281
+ const size = 8 + (index + 1) / window.misoaiMouseTrail.length * 8;
3282
+
3283
+ trailElement.style.cssText = \`
3284
+ position: fixed;
3285
+ width: \${size}px;
3286
+ height: \${size}px;
3287
+ background: ${color};
3288
+ border-radius: 50%;
3289
+ pointer-events: none;
3290
+ z-index: 999998;
3291
+ opacity: \${opacity};
3292
+ transform: translate(-50%, -50%);
3293
+ left: \${point.x}px;
3294
+ top: \${point.y}px;
3295
+ \`;
3296
+
3297
+ document.body.appendChild(trailElement);
3298
+
3299
+ // Auto-remove trail element after animation
3300
+ setTimeout(() => {
3301
+ if (trailElement.parentNode) {
3302
+ trailElement.parentNode.removeChild(trailElement);
3303
+ }
3304
+ }, 1000);
3305
+ });
3306
+ `;
3307
+ }
3308
+ function getClickAnimationScript(x, y) {
3309
+ return `
3310
+ (() => {
3311
+ const clickRipple = document.createElement('div');
3312
+ clickRipple.style.cssText = \`
3313
+ position: fixed;
3314
+ left: ${x}px;
3315
+ top: ${y}px;
3316
+ width: 0;
3317
+ height: 0;
3318
+ border: 2px solid #ff4444;
3319
+ border-radius: 50%;
3320
+ pointer-events: none;
3321
+ z-index: 999999;
3322
+ transform: translate(-50%, -50%);
3323
+ animation: misoai-click-ripple 0.6s ease-out forwards;
3324
+ \`;
3325
+
3326
+ // Add CSS animation if not exists
3327
+ if (!document.getElementById('misoai-click-styles')) {
3328
+ const style = document.createElement('style');
3329
+ style.id = 'misoai-click-styles';
3330
+ style.textContent = \`
3331
+ @keyframes misoai-click-ripple {
3332
+ 0% {
3333
+ width: 0;
3334
+ height: 0;
3335
+ opacity: 1;
3336
+ }
3337
+ 100% {
3338
+ width: 40px;
3339
+ height: 40px;
3340
+ opacity: 0;
3341
+ }
3342
+ }
3343
+ \`;
3344
+ document.head.appendChild(style);
3345
+ }
3346
+
3347
+ document.body.appendChild(clickRipple);
3348
+
3349
+ // Remove after animation
3350
+ setTimeout(() => {
3351
+ if (clickRipple.parentNode) {
3352
+ clickRipple.parentNode.removeChild(clickRipple);
3353
+ }
3354
+ }, 600);
3355
+ })();
3356
+ `;
3357
+ }
3358
+
3359
+ // src/puppeteer/base-page.ts
3094
3360
  var debugPage = (0, import_logger5.getDebug)("web:page");
3095
3361
  var Page = class {
3096
3362
  constructor(underlyingPage, pageType, opts) {
3363
+ this.currentMousePosition = { x: 0, y: 0 };
3364
+ this.mouseMovementOptions = {
3365
+ steps: 15,
3366
+ duration: 300,
3367
+ easing: "easeInOut",
3368
+ showVisualFeedback: true
3369
+ };
3370
+ this.visualFeedbackOptions = {
3371
+ pointerSize: 16,
3372
+ pointerColor: "#ff4444",
3373
+ trailLength: 4,
3374
+ showTrail: true,
3375
+ animationDuration: 150
3376
+ };
3097
3377
  this.everMoved = false;
3098
3378
  this.underlyingPage = underlyingPage;
3099
3379
  this.pageType = pageType;
3100
3380
  this.waitForNavigationTimeout = opts?.waitForNavigationTimeout ?? import_constants3.DEFAULT_WAIT_FOR_NAVIGATION_TIMEOUT;
3381
+ this.initializeMousePosition();
3101
3382
  }
3102
3383
  async evaluate(pageFunction, arg) {
3103
3384
  let result;
@@ -3116,9 +3397,76 @@ var Page = class {
3116
3397
  debugPage("evaluate function end");
3117
3398
  return result;
3118
3399
  }
3400
+ /**
3401
+ * Initialize mouse position to center of viewport
3402
+ */
3403
+ async initializeMousePosition() {
3404
+ try {
3405
+ const size = await this.size();
3406
+ this.currentMousePosition = {
3407
+ x: Math.floor(size.width / 2),
3408
+ y: Math.floor(size.height / 2)
3409
+ };
3410
+ } catch (error) {
3411
+ this.currentMousePosition = { x: 400, y: 300 };
3412
+ }
3413
+ }
3119
3414
  async evaluateJavaScript(script) {
3120
3415
  return this.evaluate(script);
3121
3416
  }
3417
+ /**
3418
+ * Show visual feedback for mouse pointer
3419
+ */
3420
+ async showMousePointer(x, y) {
3421
+ if (!this.mouseMovementOptions.showVisualFeedback)
3422
+ return;
3423
+ const script = getMousePointerScript(x, y, this.visualFeedbackOptions);
3424
+ try {
3425
+ await this.evaluate(script);
3426
+ } catch (error) {
3427
+ debugPage("Visual feedback error:", error);
3428
+ }
3429
+ }
3430
+ /**
3431
+ * Show click animation
3432
+ */
3433
+ async showClickAnimation(x, y) {
3434
+ if (!this.mouseMovementOptions.showVisualFeedback)
3435
+ return;
3436
+ const script = getClickAnimationScript(x, y);
3437
+ try {
3438
+ await this.evaluate(script);
3439
+ } catch (error) {
3440
+ debugPage("Click animation error:", error);
3441
+ }
3442
+ }
3443
+ /**
3444
+ * Move mouse with human-like movement and visual feedback
3445
+ */
3446
+ async moveMouseHumanLike(toX, toY, options) {
3447
+ const moveOptions = { ...this.mouseMovementOptions, ...options };
3448
+ const path = generateHumanMousePath(
3449
+ this.currentMousePosition,
3450
+ { x: toX, y: toY },
3451
+ moveOptions
3452
+ );
3453
+ for (let i = 0; i < path.length; i++) {
3454
+ const point = path[i];
3455
+ if (moveOptions.showVisualFeedback) {
3456
+ await this.showMousePointer(point.x, point.y);
3457
+ }
3458
+ await this.underlyingPage.mouse.move(point.x, point.y);
3459
+ this.currentMousePosition = point;
3460
+ if (i < path.length - 1) {
3461
+ const delay = calculateStepDelay(
3462
+ moveOptions.duration || 300,
3463
+ i,
3464
+ path.length
3465
+ );
3466
+ await (0, import_utils15.sleep)(delay);
3467
+ }
3468
+ }
3469
+ }
3122
3470
  async waitForNavigation() {
3123
3471
  if (this.pageType === "puppeteer" || this.pageType === "playwright") {
3124
3472
  debugPage("waitForNavigation begin");
@@ -3208,7 +3556,8 @@ var Page = class {
3208
3556
  return {
3209
3557
  click: async (x, y, options) => {
3210
3558
  await this.mouse.move(x, y);
3211
- this.underlyingPage.mouse.click(x, y, {
3559
+ await this.showClickAnimation(x, y);
3560
+ await this.underlyingPage.mouse.click(x, y, {
3212
3561
  button: options?.button || "left",
3213
3562
  count: options?.count || 1
3214
3563
  });
@@ -3228,27 +3577,23 @@ var Page = class {
3228
3577
  },
3229
3578
  move: async (x, y) => {
3230
3579
  this.everMoved = true;
3231
- return this.underlyingPage.mouse.move(x, y);
3580
+ await this.moveMouseHumanLike(x, y);
3581
+ return Promise.resolve();
3232
3582
  },
3233
3583
  drag: async (from, to) => {
3234
3584
  if (this.pageType === "puppeteer") {
3235
- await this.underlyingPage.mouse.drag(
3236
- {
3237
- x: from.x,
3238
- y: from.y
3239
- },
3240
- {
3241
- x: to.x,
3242
- y: to.y
3243
- }
3244
- );
3585
+ await this.mouse.move(from.x, from.y);
3586
+ await this.underlyingPage.mouse.down();
3587
+ await this.moveMouseHumanLike(to.x, to.y, {
3588
+ duration: 500,
3589
+ // Slower for drag operations
3590
+ steps: 25
3591
+ });
3592
+ await this.underlyingPage.mouse.up();
3245
3593
  } else if (this.pageType === "playwright") {
3246
- await this.underlyingPage.mouse.move(
3247
- from.x,
3248
- from.y
3249
- );
3594
+ await this.mouse.move(from.x, from.y);
3250
3595
  await this.underlyingPage.mouse.down();
3251
- await this.underlyingPage.mouse.move(to.x, to.y);
3596
+ await this.mouse.move(to.x, to.y);
3252
3597
  await this.underlyingPage.mouse.up();
3253
3598
  }
3254
3599
  }
@@ -3311,6 +3656,18 @@ var Page = class {
3311
3656
  await this.mouse.move(targetX, targetY);
3312
3657
  }
3313
3658
  }
3659
+ /**
3660
+ * Configure mouse movement behavior
3661
+ */
3662
+ configureMouseMovement(options) {
3663
+ this.mouseMovementOptions = { ...this.mouseMovementOptions, ...options };
3664
+ }
3665
+ /**
3666
+ * Configure visual feedback
3667
+ */
3668
+ configureVisualFeedback(options) {
3669
+ this.visualFeedbackOptions = { ...this.visualFeedbackOptions, ...options };
3670
+ }
3314
3671
  async scrollUntilTop(startingPoint) {
3315
3672
  await this.moveToPointBeforeScroll(startingPoint);
3316
3673
  return this.mouse.wheel(0, -9999999);