@web-auto/webauto 0.1.1 → 0.1.3

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 (354) hide show
  1. package/apps/desktop-console/default-settings.json +1 -0
  2. package/apps/desktop-console/dist/main/index.mjs +1618 -0
  3. package/apps/desktop-console/{src → dist}/main/preload.mjs +10 -0
  4. package/apps/desktop-console/dist/renderer/index.js +3063 -0
  5. package/apps/desktop-console/entry/ui-console.mjs +299 -0
  6. package/apps/webauto/entry/account.mjs +356 -0
  7. package/apps/webauto/entry/lib/account-detect.mjs +160 -0
  8. package/apps/webauto/entry/lib/account-store.mjs +587 -0
  9. package/apps/webauto/entry/lib/profilepool.mjs +1 -1
  10. package/apps/webauto/entry/xhs-install.mjs +27 -3
  11. package/apps/webauto/entry/xhs-status.mjs +152 -0
  12. package/apps/webauto/entry/xhs-unified.mjs +595 -17
  13. package/bin/webauto.mjs +263 -15
  14. package/dist/apps/webauto/server.js +66 -0
  15. package/dist/modules/camo-backend/src/index.js +575 -0
  16. package/dist/modules/camo-backend/src/internal/BrowserSession.js +817 -0
  17. package/dist/modules/camo-backend/src/internal/ElementRegistry.js +61 -0
  18. package/dist/modules/camo-backend/src/internal/ProfileLock.js +85 -0
  19. package/dist/modules/camo-backend/src/internal/SessionManager.js +172 -0
  20. package/dist/modules/camo-backend/src/internal/container-matcher.js +852 -0
  21. package/dist/modules/camo-backend/src/internal/engine-manager.js +258 -0
  22. package/dist/modules/camo-backend/src/internal/fingerprint.js +203 -0
  23. package/dist/modules/camo-backend/src/internal/pageRuntime.js +29 -0
  24. package/dist/modules/camo-backend/src/internal/runtimeInjector.js +30 -0
  25. package/dist/modules/camo-backend/src/internal/state-bus.js +46 -0
  26. package/dist/modules/camo-backend/src/internal/storage-paths.js +36 -0
  27. package/dist/modules/camo-backend/src/internal/ws-server.js +1202 -0
  28. package/dist/modules/camo-runtime/src/utils/browser-service.mjs +423 -0
  29. package/dist/modules/camo-runtime/src/utils/config.mjs +77 -0
  30. package/dist/modules/container-registry/src/index.js +184 -0
  31. package/dist/modules/logging/src/index.js +92 -0
  32. package/dist/modules/operations/src/builtin.js +27 -0
  33. package/dist/modules/operations/src/container-binding.js +75 -0
  34. package/dist/modules/operations/src/executor.js +146 -0
  35. package/dist/modules/operations/src/operations/click.js +167 -0
  36. package/dist/modules/operations/src/operations/extract.js +204 -0
  37. package/dist/modules/operations/src/operations/find-child.js +17 -0
  38. package/dist/modules/operations/src/operations/highlight.js +138 -0
  39. package/dist/modules/operations/src/operations/key.js +61 -0
  40. package/dist/modules/operations/src/operations/navigate.js +148 -0
  41. package/dist/modules/operations/src/operations/scroll.js +126 -0
  42. package/dist/modules/operations/src/operations/type.js +190 -0
  43. package/dist/modules/operations/src/queue.js +100 -0
  44. package/dist/modules/operations/src/registry.js +11 -0
  45. package/dist/modules/operations/src/system/mouse.js +33 -0
  46. package/dist/modules/state/src/atomic-json.js +33 -0
  47. package/dist/modules/workflow/blocks/AnchorVerificationBlock.js +71 -0
  48. package/dist/modules/workflow/blocks/BehaviorRandomizer.js +26 -0
  49. package/dist/modules/workflow/blocks/CallWorkflowBlock.js +38 -0
  50. package/dist/modules/workflow/blocks/CloseDetailBlock.js +209 -0
  51. package/dist/modules/workflow/blocks/CollectBatch.js +137 -0
  52. package/dist/modules/workflow/blocks/CollectCommentsBlock.js +415 -0
  53. package/dist/modules/workflow/blocks/CollectSearchListBlock.js +599 -0
  54. package/dist/modules/workflow/blocks/CollectWeiboPosts.js +229 -0
  55. package/dist/modules/workflow/blocks/DetectPageStateBlock.js +259 -0
  56. package/dist/modules/workflow/blocks/EnsureLoginBlock.js +162 -0
  57. package/dist/modules/workflow/blocks/EnsureSession.js +426 -0
  58. package/dist/modules/workflow/blocks/ErrorClassifier.js +164 -0
  59. package/dist/modules/workflow/blocks/ErrorRecoveryBlock.js +319 -0
  60. package/dist/modules/workflow/blocks/ExpandCommentsBlock.js +1032 -0
  61. package/dist/modules/workflow/blocks/ExtractDetailBlock.js +310 -0
  62. package/dist/modules/workflow/blocks/ExtractPostFields.js +88 -0
  63. package/dist/modules/workflow/blocks/GenerateSmartReplyBlock.js +68 -0
  64. package/dist/modules/workflow/blocks/GoToSearchBlock.js +497 -0
  65. package/dist/modules/workflow/blocks/GracefulFallbackBlock.js +104 -0
  66. package/dist/modules/workflow/blocks/HighlightBlock.js +66 -0
  67. package/dist/modules/workflow/blocks/InitAutoScroll.js +65 -0
  68. package/dist/modules/workflow/blocks/LoadContainerDefinition.js +50 -0
  69. package/dist/modules/workflow/blocks/LoadContainerIndex.js +43 -0
  70. package/dist/modules/workflow/blocks/LocateAndGuardBlock.js +176 -0
  71. package/dist/modules/workflow/blocks/LoginRecoveryBlock.js +242 -0
  72. package/dist/modules/workflow/blocks/MatchContainers.js +64 -0
  73. package/dist/modules/workflow/blocks/MonitoringBlock.js +190 -0
  74. package/dist/modules/workflow/blocks/OpenDetailBlock.js +1240 -0
  75. package/dist/modules/workflow/blocks/OrganizeXhsNotesBlock.js +117 -0
  76. package/dist/modules/workflow/blocks/PersistXhsNoteBlock.js +270 -0
  77. package/dist/modules/workflow/blocks/PickSinglePost.js +69 -0
  78. package/dist/modules/workflow/blocks/ProgressTracker.js +125 -0
  79. package/dist/modules/workflow/blocks/RecordFixtureBlock.js +44 -0
  80. package/dist/modules/workflow/blocks/RenderMarkdown.js +48 -0
  81. package/dist/modules/workflow/blocks/SaveFile.js +54 -0
  82. package/dist/modules/workflow/blocks/ScrollNextBatch.js +72 -0
  83. package/dist/modules/workflow/blocks/SessionHealthBlock.js +73 -0
  84. package/dist/modules/workflow/blocks/StartBrowserService.js +45 -0
  85. package/dist/modules/workflow/blocks/ValidateContainerDefinition.js +67 -0
  86. package/dist/modules/workflow/blocks/ValidateExtract.js +35 -0
  87. package/dist/modules/workflow/blocks/WaitSearchPermitBlock.js +162 -0
  88. package/dist/modules/workflow/blocks/WaitStable.js +74 -0
  89. package/dist/modules/workflow/blocks/WarmupCommentsBlock.js +120 -0
  90. package/dist/modules/workflow/blocks/WorkflowExecutor.js +156 -0
  91. package/dist/modules/workflow/blocks/XiaohongshuCollectFromLinksBlock.js +1004 -0
  92. package/dist/modules/workflow/blocks/XiaohongshuCollectLinksBlock.js +1049 -0
  93. package/dist/modules/workflow/blocks/XiaohongshuFullCollectBlock.js +782 -0
  94. package/dist/modules/workflow/blocks/helpers/anchorVerify.js +198 -0
  95. package/dist/modules/workflow/blocks/helpers/asyncWorkQueue.js +53 -0
  96. package/dist/modules/workflow/blocks/helpers/commentScroller.js +334 -0
  97. package/dist/modules/workflow/blocks/helpers/commentSectionLocator.js +126 -0
  98. package/dist/modules/workflow/blocks/helpers/containerAnchors.js +301 -0
  99. package/dist/modules/workflow/blocks/helpers/debugArtifacts.js +6 -0
  100. package/dist/modules/workflow/blocks/helpers/downloadPaths.js +29 -0
  101. package/dist/modules/workflow/blocks/helpers/expandCommentsController.js +53 -0
  102. package/dist/modules/workflow/blocks/helpers/expandCommentsExtractor.js +129 -0
  103. package/dist/modules/workflow/blocks/helpers/macosVisionOcrPlugin.js +116 -0
  104. package/dist/modules/workflow/blocks/helpers/mergeXhsMarkdown.js +109 -0
  105. package/dist/modules/workflow/blocks/helpers/openDetailController.js +56 -0
  106. package/dist/modules/workflow/blocks/helpers/openDetailTypes.js +7 -0
  107. package/dist/modules/workflow/blocks/helpers/openDetailViewport.js +474 -0
  108. package/dist/modules/workflow/blocks/helpers/openDetailWaiter.js +104 -0
  109. package/dist/modules/workflow/blocks/helpers/operationLogger.js +195 -0
  110. package/dist/modules/workflow/blocks/helpers/persistedNotes.js +107 -0
  111. package/dist/modules/workflow/blocks/helpers/replyExpander.js +260 -0
  112. package/dist/modules/workflow/blocks/helpers/scrollIntoView.js +138 -0
  113. package/dist/modules/workflow/blocks/helpers/searchExecutor.js +328 -0
  114. package/dist/modules/workflow/blocks/helpers/searchGate.js +46 -0
  115. package/dist/modules/workflow/blocks/helpers/searchPageState.js +164 -0
  116. package/dist/modules/workflow/blocks/helpers/searchResultWaiter.js +64 -0
  117. package/dist/modules/workflow/blocks/helpers/simpleAnchor.js +134 -0
  118. package/dist/modules/workflow/blocks/helpers/smartReply.js +40 -0
  119. package/dist/modules/workflow/blocks/helpers/systemInput.js +635 -0
  120. package/dist/modules/workflow/blocks/helpers/targetCountMode.js +9 -0
  121. package/dist/modules/workflow/blocks/helpers/xhsCliArgs.js +80 -0
  122. package/dist/modules/workflow/blocks/helpers/xhsCommentDom.js +805 -0
  123. package/dist/modules/workflow/blocks/helpers/xhsNoteOrganizer.js +140 -0
  124. package/dist/modules/workflow/blocks/restore/RestorePhaseBlock.js +204 -0
  125. package/dist/modules/workflow/config/workflowRegistry.js +32 -0
  126. package/dist/modules/workflow/definitions/batch-collect-workflow.js +63 -0
  127. package/dist/modules/workflow/definitions/scroll-extract-workflow.js +74 -0
  128. package/dist/modules/workflow/definitions/xiaohongshu-collect-workflow-v2.js +81 -0
  129. package/dist/modules/workflow/definitions/xiaohongshu-collect-workflow.js +57 -0
  130. package/dist/modules/workflow/definitions/xiaohongshu-full-collect-workflow-v3.js +68 -0
  131. package/dist/modules/workflow/definitions/xiaohongshu-note-collect.js +49 -0
  132. package/dist/modules/workflow/definitions/xiaohongshu-phase1-workflow-v3.js +30 -0
  133. package/dist/modules/workflow/definitions/xiaohongshu-phase2-links-workflow-v3.js +40 -0
  134. package/dist/modules/workflow/definitions/xiaohongshu-phase3-collect-workflow-v1.js +54 -0
  135. package/dist/modules/workflow/definitions/xiaohongshu-phase34-from-links-workflow-v3.js +25 -0
  136. package/dist/modules/workflow/src/WeiboEventDrivenWorkflowRunner.js +308 -0
  137. package/dist/modules/workflow/src/context.js +70 -0
  138. package/dist/modules/workflow/src/index.js +5 -0
  139. package/dist/modules/workflow/src/orchestrator.js +230 -0
  140. package/dist/modules/workflow/src/runner.js +55 -0
  141. package/dist/modules/workflow/src/runtime.js +70 -0
  142. package/dist/modules/workflow/workflows/WeiboFeedExtractionWorkflow.js +359 -0
  143. package/dist/modules/workflow/workflows/XiaohongshuLoginWorkflow.js +110 -0
  144. package/dist/modules/xiaohongshu/app/src/blocks/MatchCommentsBlock.js +139 -0
  145. package/dist/modules/xiaohongshu/app/src/blocks/Phase1EnsureServicesBlock.js +36 -0
  146. package/dist/modules/xiaohongshu/app/src/blocks/Phase1MonitorCookieBlock.js +213 -0
  147. package/dist/modules/xiaohongshu/app/src/blocks/Phase1StartProfileBlock.js +121 -0
  148. package/dist/modules/xiaohongshu/app/src/blocks/Phase2CollectLinksBlock.js +1249 -0
  149. package/dist/modules/xiaohongshu/app/src/blocks/Phase2SearchBlock.js +703 -0
  150. package/dist/modules/xiaohongshu/app/src/blocks/Phase34CloseDetailBlock.js +41 -0
  151. package/dist/modules/xiaohongshu/app/src/blocks/Phase34CloseTabsBlock.js +44 -0
  152. package/dist/modules/xiaohongshu/app/src/blocks/Phase34CollectCommentsBlock.js +150 -0
  153. package/dist/modules/xiaohongshu/app/src/blocks/Phase34ExtractDetailBlock.js +117 -0
  154. package/dist/modules/xiaohongshu/app/src/blocks/Phase34OpenDetailBlock.js +102 -0
  155. package/dist/modules/xiaohongshu/app/src/blocks/Phase34OpenTabsBlock.js +109 -0
  156. package/dist/modules/xiaohongshu/app/src/blocks/Phase34PersistDetailBlock.js +117 -0
  157. package/dist/modules/xiaohongshu/app/src/blocks/Phase34ProcessSingleNoteBlock.js +114 -0
  158. package/dist/modules/xiaohongshu/app/src/blocks/Phase34ValidateLinksBlock.js +90 -0
  159. package/dist/modules/xiaohongshu/app/src/blocks/Phase3InteractBlock.js +1009 -0
  160. package/dist/modules/xiaohongshu/app/src/blocks/Phase4MultiTabHarvestBlock.js +233 -0
  161. package/dist/modules/xiaohongshu/app/src/blocks/ReplyInteractBlock.js +291 -0
  162. package/dist/modules/xiaohongshu/app/src/blocks/XhsDiscoverFallbackBlock.js +240 -0
  163. package/dist/modules/xiaohongshu/app/src/blocks/helpers/commentMatchDsl.js +126 -0
  164. package/dist/modules/xiaohongshu/app/src/blocks/helpers/commentMatcher.js +99 -0
  165. package/dist/modules/xiaohongshu/app/src/blocks/helpers/evidence.js +27 -0
  166. package/dist/modules/xiaohongshu/app/src/blocks/helpers/sharding.js +42 -0
  167. package/dist/modules/xiaohongshu/app/src/blocks/helpers/xhsComments.js +270 -0
  168. package/dist/modules/xiaohongshu/app/src/index.js +9 -0
  169. package/dist/modules/xiaohongshu/app/src/utils/checkpoints.js +222 -0
  170. package/dist/modules/xiaohongshu/app/src/utils/controllerAction.js +43 -0
  171. package/dist/services/controller/src/controller.js +1476 -0
  172. package/dist/services/controller/src/index.js +2 -0
  173. package/dist/services/controller/src/payload-normalizer.js +129 -0
  174. package/dist/services/shared/heartbeat.js +120 -0
  175. package/dist/services/shared/lib/errorHandler.js +2 -0
  176. package/dist/services/shared/serviceProcessLogger.js +139 -0
  177. package/dist/services/unified-api/RemoteBrowserSession.js +176 -0
  178. package/dist/services/unified-api/RemoteSessionManager.js +148 -0
  179. package/dist/services/unified-api/container-operations-handler.js +115 -0
  180. package/dist/services/unified-api/server.js +652 -0
  181. package/dist/services/unified-api/state-registry.js +274 -0
  182. package/dist/services/unified-api/task-persistence.js +66 -0
  183. package/dist/services/unified-api/task-state.js +130 -0
  184. package/modules/camo-runtime/src/autoscript/action-providers/xhs/search.mjs +12 -5
  185. package/modules/xiaohongshu/app/pnpm-lock.yaml +24 -0
  186. package/package.json +38 -10
  187. package/.beads/README.md +0 -81
  188. package/.beads/config.yaml +0 -67
  189. package/.beads/interactions.jsonl +0 -0
  190. package/.beads/issues.jsonl +0 -180
  191. package/.beads/metadata.json +0 -4
  192. package/.claude/settings.local.json +0 -10
  193. package/.github/workflows/ci.yml +0 -55
  194. package/AGENTS.md +0 -253
  195. package/apps/desktop-console/README.md +0 -27
  196. package/apps/desktop-console/package-lock.json +0 -897
  197. package/apps/desktop-console/package.json +0 -20
  198. package/apps/desktop-console/scripts/build-and-install.mjs +0 -19
  199. package/apps/desktop-console/scripts/build.mjs +0 -45
  200. package/apps/desktop-console/scripts/test-preload.mjs +0 -13
  201. package/apps/desktop-console/src/main/config.mts +0 -26
  202. package/apps/desktop-console/src/main/core-daemon-manager.mts +0 -131
  203. package/apps/desktop-console/src/main/desktop-settings.mts +0 -267
  204. package/apps/desktop-console/src/main/heartbeat-watchdog.mts +0 -50
  205. package/apps/desktop-console/src/main/heartbeat-watchdog.test.mts +0 -68
  206. package/apps/desktop-console/src/main/index-streaming.test.mts +0 -20
  207. package/apps/desktop-console/src/main/index.mts +0 -980
  208. package/apps/desktop-console/src/main/profile-store.mts +0 -239
  209. package/apps/desktop-console/src/main/profile-store.test.mts +0 -54
  210. package/apps/desktop-console/src/main/state-bridge.mts +0 -114
  211. package/apps/desktop-console/src/main/task-state-types.ts +0 -32
  212. package/apps/desktop-console/src/renderer/hooks/use-task-state.mts +0 -120
  213. package/apps/desktop-console/src/renderer/index.mts +0 -133
  214. package/apps/desktop-console/src/renderer/index.test.mts +0 -34
  215. package/apps/desktop-console/src/renderer/path-helpers.mts +0 -46
  216. package/apps/desktop-console/src/renderer/path-helpers.test.mts +0 -14
  217. package/apps/desktop-console/src/renderer/tabs/debug.mts +0 -48
  218. package/apps/desktop-console/src/renderer/tabs/debug.test.mts +0 -22
  219. package/apps/desktop-console/src/renderer/tabs/logs.mts +0 -421
  220. package/apps/desktop-console/src/renderer/tabs/logs.test.mts +0 -27
  221. package/apps/desktop-console/src/renderer/tabs/preflight.mts +0 -486
  222. package/apps/desktop-console/src/renderer/tabs/preflight.test.mts +0 -33
  223. package/apps/desktop-console/src/renderer/tabs/profile-pool.mts +0 -213
  224. package/apps/desktop-console/src/renderer/tabs/results.mts +0 -171
  225. package/apps/desktop-console/src/renderer/tabs/run.test.mts +0 -63
  226. package/apps/desktop-console/src/renderer/tabs/runtime.mts +0 -151
  227. package/apps/desktop-console/src/renderer/tabs/settings.mts +0 -146
  228. package/apps/desktop-console/src/renderer/tabs/xiaohongshu/account-flow.mts +0 -486
  229. package/apps/desktop-console/src/renderer/tabs/xiaohongshu/guide-browser-check.mts +0 -56
  230. package/apps/desktop-console/src/renderer/tabs/xiaohongshu/helpers.mts +0 -262
  231. package/apps/desktop-console/src/renderer/tabs/xiaohongshu/layout-block.mts +0 -430
  232. package/apps/desktop-console/src/renderer/tabs/xiaohongshu/live-stats.mts +0 -847
  233. package/apps/desktop-console/src/renderer/tabs/xiaohongshu/run-flow.mts +0 -443
  234. package/apps/desktop-console/src/renderer/tabs/xiaohongshu-state.mts +0 -425
  235. package/apps/desktop-console/src/renderer/tabs/xiaohongshu.mts +0 -497
  236. package/apps/desktop-console/src/renderer/tabs/xiaohongshu.test.mts +0 -291
  237. package/apps/desktop-console/src/renderer/ui-components.mts +0 -31
  238. package/docs/README_camoufox_chinese.md +0 -141
  239. package/docs/USAGE_V3.md +0 -163
  240. package/docs/arch/OCR_MACOS_PLUGIN.md +0 -39
  241. package/docs/arch/PORTS.md +0 -40
  242. package/docs/arch/REGRESSION_CHECKLIST.md +0 -121
  243. package/docs/arch/SEARCH_GATE.md +0 -224
  244. package/docs/arch/VIEWPORT_SAFETY.md +0 -182
  245. package/docs/arch/XIAOHONGSHU_OFFLINE_MOCK_DESIGN.md +0 -267
  246. package/docs/xiaohongshu-container-driven-summary.md +0 -221
  247. package/docs/xiaohongshu-full-collect-runbook.md +0 -134
  248. package/docs/xiaohongshu-next-steps.md +0 -228
  249. package/docs/xiaohongshu-quickstart.md +0 -73
  250. package/docs/xiaohongshu-workflow-summary.md +0 -227
  251. package/modules/container-registry/tests/container-registry.test.ts +0 -16
  252. package/modules/logging/tests/logging.test.ts +0 -38
  253. package/modules/operations/tests/operations.test.ts +0 -22
  254. package/modules/operations/tests/viewport-filter.test.ts +0 -161
  255. package/modules/operations/tests/visible-only.test.ts +0 -250
  256. package/modules/session-manager/tests/session-manager.test.ts +0 -23
  257. package/modules/state/src/atomic-json.test.ts +0 -30
  258. package/modules/state/src/paths.test.ts +0 -59
  259. package/modules/state/src/xiaohongshu-collect-state.test.ts +0 -259
  260. package/modules/workflow/blocks/AnchorVerificationBlock.d.ts.map +0 -1
  261. package/modules/workflow/blocks/AnchorVerificationBlock.js.map +0 -1
  262. package/modules/workflow/blocks/DetectPageStateBlock.d.ts.map +0 -1
  263. package/modules/workflow/blocks/DetectPageStateBlock.js.map +0 -1
  264. package/modules/workflow/blocks/ErrorRecoveryBlock.d.ts.map +0 -1
  265. package/modules/workflow/blocks/ErrorRecoveryBlock.js.map +0 -1
  266. package/modules/workflow/blocks/WaitSearchPermitBlock.d.ts.map +0 -1
  267. package/modules/workflow/blocks/WaitSearchPermitBlock.js.map +0 -1
  268. package/modules/workflow/blocks/helpers/containerAnchors.d.ts.map +0 -1
  269. package/modules/workflow/blocks/helpers/containerAnchors.js.map +0 -1
  270. package/modules/workflow/blocks/helpers/downloadPaths.test.ts +0 -62
  271. package/modules/workflow/blocks/helpers/mergeXhsMarkdown.test.ts +0 -121
  272. package/modules/workflow/blocks/helpers/operationLogger.d.ts.map +0 -1
  273. package/modules/workflow/blocks/helpers/operationLogger.js.map +0 -1
  274. package/modules/workflow/blocks/helpers/persistedNotes.test.ts +0 -268
  275. package/modules/workflow/blocks/helpers/searchPageState.d.ts.map +0 -1
  276. package/modules/workflow/blocks/helpers/searchPageState.js.map +0 -1
  277. package/modules/workflow/blocks/helpers/targetCountMode.test.ts +0 -29
  278. package/modules/workflow/blocks/helpers/xhsCliArgs.test.ts +0 -75
  279. package/modules/workflow/tests/smartReply.test.ts +0 -32
  280. package/modules/xiaohongshu/app/src/blocks/Phase3Interact.matcher.test.ts +0 -33
  281. package/modules/xiaohongshu/app/src/utils/__tests__/checkpoints.test.ts +0 -141
  282. package/modules/xiaohongshu/app/tests/commentMatchDsl.test.ts +0 -50
  283. package/modules/xiaohongshu/app/tests/commentMatcher.test.ts +0 -46
  284. package/modules/xiaohongshu/app/tests/sharding.test.ts +0 -31
  285. package/package-scripts.json +0 -8
  286. package/runtime/infra/utils/README.md +0 -13
  287. package/runtime/infra/utils/scripts/README.md +0 -0
  288. package/runtime/infra/utils/scripts/development/eval-in-session.mjs +0 -40
  289. package/runtime/infra/utils/scripts/development/highlight-search-containers.mjs +0 -35
  290. package/runtime/infra/utils/scripts/service/kill-port.mjs +0 -24
  291. package/runtime/infra/utils/scripts/service/start-api.mjs +0 -39
  292. package/runtime/infra/utils/scripts/service/start-browser-service.mjs +0 -106
  293. package/runtime/infra/utils/scripts/service/stop-api.mjs +0 -18
  294. package/runtime/infra/utils/scripts/service/stop-browser-service.mjs +0 -104
  295. package/runtime/infra/utils/scripts/test-services.mjs +0 -94
  296. package/services/shared/heartbeat.test.ts +0 -102
  297. package/services/unified-api/__tests__/task-state.test.ts +0 -95
  298. package/sitecustomize.py +0 -19
  299. package/tests/README.md +0 -194
  300. package/tests/e2e/workflows/weibo-feed-extraction.test.ts +0 -171
  301. package/tests/fixtures/data/container-definitions.json +0 -67
  302. package/tests/fixtures/pages/simple-page.html +0 -69
  303. package/tests/integration/01-test-container-match.mjs +0 -188
  304. package/tests/integration/02-test-dom-branch.mjs +0 -161
  305. package/tests/integration/03-test-container-operation-system.mjs +0 -91
  306. package/tests/integration/05-test-container-lifecycle-events.mjs +0 -224
  307. package/tests/integration/05-test-container-lifecycle-with-events.mjs +0 -250
  308. package/tests/integration/06-test-container-dom-tree-drawing.mjs +0 -256
  309. package/tests/integration/07-test-weibo-container-lifecycle.mjs +0 -355
  310. package/tests/integration/08-test-weibo-feed-workflow.test.mjs +0 -164
  311. package/tests/integration/10-test-visual-analyzer.mjs +0 -312
  312. package/tests/integration/11-test-visual-loop.mjs +0 -284
  313. package/tests/integration/12-test-simple-visual-loop.mjs +0 -242
  314. package/tests/integration/13-test-visual-robust.mjs +0 -185
  315. package/tests/integration/14-test-visual-highlight-loop.mjs +0 -271
  316. package/tests/integration/inspect-page.mjs +0 -50
  317. package/tests/integration/run-all-tests.mjs +0 -95
  318. package/tests/patch_verification/CODEX_PATCH_TEST.md +0 -103
  319. package/tests/patch_verification/PHASE2_ANALYSIS.md +0 -179
  320. package/tests/patch_verification/PHASE2_OPTIMIZATION_REPORT.md +0 -55
  321. package/tests/patch_verification/PHASE2_TO_PHASE4_SUMMARY.md +0 -126
  322. package/tests/patch_verification/QUICK_TEST_SEQUENCE.md +0 -262
  323. package/tests/patch_verification/README.md +0 -143
  324. package/tests/patch_verification/RUN_TESTS.md +0 -60
  325. package/tests/patch_verification/TEST_EXECUTION.md +0 -99
  326. package/tests/patch_verification/TEST_PLAN.md +0 -328
  327. package/tests/patch_verification/TEST_RESULTS.md +0 -34
  328. package/tests/patch_verification/TOOL_TEST_PLAN.md +0 -48
  329. package/tests/patch_verification/run-tool-test.mjs +0 -121
  330. package/tests/patch_verification/temp_test_files/test01.txt +0 -1
  331. package/tests/patch_verification/temp_test_files/test02.txt +0 -3
  332. package/tests/patch_verification/temp_test_files/test02_gnu.txt +0 -3
  333. package/tests/patch_verification/temp_test_files/test03.txt +0 -1
  334. package/tests/patch_verification/temp_test_files/test03_multiline.txt +0 -5
  335. package/tests/patch_verification/temp_test_files/test04_function.ts +0 -5
  336. package/tests/patch_verification/temp_test_files/test05_import.ts +0 -4
  337. package/tests/patch_verification/temp_test_files/test06_special_chars.txt +0 -4
  338. package/tests/patch_verification/temp_test_files/test07_indentation.ts +0 -5
  339. package/tests/patch_verification/temp_test_files/test08_mismatch.txt +0 -1
  340. package/tests/patch_verification/temp_test_files/test_add_02.txt +0 -3
  341. package/tests/patch_verification/temp_test_files/test_simple.txt +0 -1
  342. package/tests/runner/TestReporter.mjs +0 -57
  343. package/tests/runner/TestRunner.mjs +0 -244
  344. package/tests/unit/commands/profile.test.mjs +0 -10
  345. package/tests/unit/container/change-notifier.test.mjs +0 -181
  346. package/tests/unit/lifecycle/session-registry.test.mjs +0 -135
  347. package/tests/unit/operations/registry.test.ts +0 -73
  348. package/tests/unit/utils/browser-service.test.mjs +0 -153
  349. package/tests/unit/utils/config.test.mjs +0 -166
  350. package/tests/unit/utils/fingerprint.test.mjs +0 -166
  351. package/tsconfig.json +0 -31
  352. package/tsconfig.services.json +0 -26
  353. /package/apps/desktop-console/{src → dist}/renderer/index.html +0 -0
  354. /package/apps/desktop-console/{src/renderer/tabs → dist/renderer}/run.mts +0 -0
@@ -0,0 +1,126 @@
1
+ async function runScroll(ctx, config) {
2
+ const rawDistance = typeof config.distance === 'number'
3
+ ? config.distance
4
+ : typeof config.amount === 'number'
5
+ ? config.amount
6
+ : 500;
7
+ const direction = config.direction || 'down';
8
+ const fullyVisible = config.fullyVisible === true;
9
+ const anchor = config.anchor ?? null;
10
+ // 单次滚动约束:不超过 800px,符合“用户手势范围”
11
+ const distance = Math.min(800, Math.max(0, Math.floor(Math.abs(rawDistance))));
12
+ const deltaY = direction === 'up' ? -distance : distance;
13
+ const useSystemMouse = config.useSystemMouse !== false;
14
+ const protocolMouse = ctx.page?.mouse;
15
+ if (useSystemMouse && !ctx.systemInput?.mouseWheel) {
16
+ return { success: false, error: 'system scroll not available' };
17
+ }
18
+ // 优先鼠标滚轮(系统级或协议级)
19
+ if ((useSystemMouse && ctx.systemInput?.mouseWheel) || (!useSystemMouse && protocolMouse?.wheel)) {
20
+ const selector = typeof config.selector === 'string' ? config.selector.trim() : '';
21
+ if (selector) {
22
+ const info = await ctx.page.evaluate(({ sel, fVisible, anchorPoint }) => {
23
+ const isVisible = (el) => {
24
+ const r = el.getBoundingClientRect();
25
+ return r.width > 0 && r.height > 0 && r.bottom > 0 && r.top < window.innerHeight && r.right > 0 && r.left < window.innerWidth;
26
+ };
27
+ const isFullyVisible = (el) => {
28
+ const r = el.getBoundingClientRect();
29
+ return r.width > 0 && r.height > 0 && r.top >= 0 && r.left >= 0 && r.bottom <= window.innerHeight && r.right <= window.innerWidth;
30
+ };
31
+ const el = document.querySelector(sel);
32
+ if (!el)
33
+ return null;
34
+ const r = el.getBoundingClientRect();
35
+ const visible = isVisible(el);
36
+ const fVisibleCheck = isFullyVisible(el);
37
+ if (!visible)
38
+ return { visible: false, fullyVisible: false, anchorMatch: false, points: [] };
39
+ if (fVisible && !fVisibleCheck)
40
+ return { visible, fullyVisible: false, anchorMatch: false, points: [] };
41
+ let anchorMatch = true;
42
+ if (anchorPoint) {
43
+ const hit = document.elementFromPoint(anchorPoint.x, anchorPoint.y);
44
+ anchorMatch = hit !== null && (hit === el || el.contains(hit));
45
+ if (!anchorMatch)
46
+ return { visible, fullyVisible: fVisibleCheck, anchorMatch: false, points: [] };
47
+ }
48
+ const x1 = Math.max(0, r.left);
49
+ const y1 = Math.max(0, r.top);
50
+ const x2 = Math.min(window.innerWidth, r.right);
51
+ const y2 = Math.min(window.innerHeight, r.bottom);
52
+ const mx = Math.round((x1 + x2) / 2);
53
+ const pad = 24;
54
+ const points = [
55
+ { x: mx, y: Math.round(y1 + pad) }, // top-middle (avoid center overlays)
56
+ { x: mx, y: Math.round((y1 + y2) / 2) }, // middle
57
+ { x: mx, y: Math.round(y2 - pad) }, // bottom-middle
58
+ { x: Math.round(x1 + pad), y: Math.round(y1 + pad) }, // top-left
59
+ { x: Math.round(x2 - pad), y: Math.round(y1 + pad) }, // top-right
60
+ ];
61
+ const ok = [];
62
+ for (const p of points) {
63
+ if (!Number.isFinite(p.x) || !Number.isFinite(p.y))
64
+ continue;
65
+ if (p.x < 0 || p.y < 0 || p.x > window.innerWidth || p.y > window.innerHeight)
66
+ continue;
67
+ const hit = document.elementFromPoint(p.x, p.y);
68
+ if (hit && (hit === el || el.contains(hit))) {
69
+ ok.push(p);
70
+ }
71
+ }
72
+ if (!ok.length)
73
+ ok.push({ x: mx, y: Math.round((y1 + y2) / 2) });
74
+ return { visible: true, fullyVisible: fVisibleCheck, anchorMatch, points: ok };
75
+ }, { sel: selector, fVisible: fullyVisible, anchorPoint: anchor });
76
+ if (!info) {
77
+ return { success: false, error: 'element not found' };
78
+ }
79
+ if (!info.visible) {
80
+ return { success: false, error: 'element not visible' };
81
+ }
82
+ if (fullyVisible && !info.fullyVisible) {
83
+ return { success: false, error: 'element not fully visible in viewport' };
84
+ }
85
+ if (anchor && !info.anchorMatch) {
86
+ return { success: false, error: 'anchor point does not hit target element' };
87
+ }
88
+ if (Array.isArray(info.points) && info.points.length > 0) {
89
+ const p = info.points[0];
90
+ const x = Math.round(p.x);
91
+ const y = Math.round(p.y);
92
+ if (useSystemMouse) {
93
+ if (ctx.systemInput?.mouseMove) {
94
+ await ctx.systemInput.mouseMove(x, y, 2);
95
+ }
96
+ }
97
+ else if (protocolMouse && typeof protocolMouse.move === 'function') {
98
+ await protocolMouse.move(x, y, { steps: 2 });
99
+ }
100
+ await new Promise((r) => setTimeout(r, 80));
101
+ }
102
+ }
103
+ if (useSystemMouse) {
104
+ await ctx.systemInput.mouseWheel(0, deltaY);
105
+ }
106
+ else {
107
+ await protocolMouse.wheel(0, deltaY);
108
+ }
109
+ return { success: true, deltaY, inputMode: useSystemMouse ? 'system' : 'protocol' };
110
+ }
111
+ // fallback:系统键盘滚动(PageDown / PageUp)
112
+ const keyboard = ctx.page.keyboard;
113
+ if (keyboard?.press) {
114
+ const key = direction === 'up' ? 'PageUp' : 'PageDown';
115
+ await keyboard.press(key);
116
+ return { success: true, key, inputMode: useSystemMouse ? 'system' : 'protocol' };
117
+ }
118
+ return { success: false, error: 'no scroll capability available' };
119
+ }
120
+ export const scrollOperation = {
121
+ id: 'scroll',
122
+ description: 'Scroll page or target element',
123
+ requiredCapabilities: ['scroll'],
124
+ run: runScroll,
125
+ };
126
+ //# sourceMappingURL=scroll.js.map
@@ -0,0 +1,190 @@
1
+ async function runType(ctx, config) {
2
+ const selector = typeof config.selector === 'string' ? config.selector.trim() : '';
3
+ if (!selector) {
4
+ return { success: false, error: 'selector required for type operation' };
5
+ }
6
+ const index = Number.isFinite(config.index) ? Math.max(0, Math.floor(config.index)) : 0;
7
+ const keyboard = ctx.page.keyboard;
8
+ const fullyVisible = config.fullyVisible !== false;
9
+ const anchor = config.anchor ?? null;
10
+ const useSystemMouse = config.useSystemMouse !== false;
11
+ const protocolMouse = ctx.page?.mouse;
12
+ if (useSystemMouse && !ctx.systemInput?.mouseClick) {
13
+ return { success: false, error: 'system mouse not available' };
14
+ }
15
+ if (!useSystemMouse && (!protocolMouse || typeof protocolMouse.click !== 'function')) {
16
+ return { success: false, error: 'protocol mouse not available' };
17
+ }
18
+ if (!keyboard || typeof keyboard.type !== 'function') {
19
+ return { success: false, error: 'keyboard type not available' };
20
+ }
21
+ const getClickableRect = async () => ctx.page.evaluate(({ sel, idx, fVisible, anchorPoint }) => {
22
+ const isVisible = (el) => {
23
+ const r = el.getBoundingClientRect();
24
+ return r.width > 0 && r.height > 0 && r.bottom > 0 && r.top < window.innerHeight && r.right > 0 && r.left < window.innerWidth;
25
+ };
26
+ const isFullyVisible = (el) => {
27
+ const r = el.getBoundingClientRect();
28
+ return r.width > 0 && r.height > 0 && r.top >= 0 && r.left >= 0 && r.bottom <= window.innerHeight && r.right <= window.innerWidth;
29
+ };
30
+ const nodes = Array.from(document.querySelectorAll(sel));
31
+ const candidates = nodes.filter((n) => isVisible(n));
32
+ const root = candidates[idx];
33
+ if (!root)
34
+ return null;
35
+ const focusEl = root instanceof HTMLInputElement ||
36
+ root instanceof HTMLTextAreaElement ||
37
+ (root instanceof HTMLElement && root.isContentEditable)
38
+ ? root
39
+ : root.querySelector('input,textarea,[contenteditable="true"],[contenteditable="plaintext-only"]') ||
40
+ root;
41
+ const r = focusEl.getBoundingClientRect();
42
+ const visible = isVisible(focusEl);
43
+ const fVisibleCheck = isFullyVisible(focusEl);
44
+ if (!visible)
45
+ return { x1: r.left, y1: r.top, x2: r.right, y2: r.bottom, visible: false, fullyVisible: false, anchorMatch: false, clickPoints: [] };
46
+ if (fVisible && !fVisible)
47
+ return { x1: r.left, y1: r.top, x2: r.right, y2: r.bottom, visible, fullyVisible: false, anchorMatch: false, clickPoints: [] };
48
+ let anchorMatch = true;
49
+ if (anchorPoint) {
50
+ const hit = document.elementFromPoint(anchorPoint.x, anchorPoint.y);
51
+ anchorMatch = hit !== null && (hit === focusEl || focusEl.contains(hit));
52
+ if (!anchorMatch)
53
+ return { x1: r.left, y1: r.top, x2: r.right, y2: r.bottom, visible, fullyVisible: fVisibleCheck, anchorMatch: false, clickPoints: [] };
54
+ }
55
+ const midY = Math.round((r.top + r.bottom) / 2);
56
+ const points = [
57
+ { x: Math.round((r.left + r.right) / 2), y: midY },
58
+ { x: Math.round(r.left + 8), y: midY },
59
+ { x: Math.round(r.right - 8), y: midY },
60
+ ];
61
+ const clickPoints = [];
62
+ for (const p of points) {
63
+ if (!Number.isFinite(p.x) || !Number.isFinite(p.y))
64
+ continue;
65
+ const hit = document.elementFromPoint(p.x, p.y);
66
+ if (hit && (hit === focusEl || focusEl.contains(hit))) {
67
+ clickPoints.push(p);
68
+ }
69
+ }
70
+ if (!clickPoints.length)
71
+ clickPoints.push(points[0]);
72
+ return { x1: r.left, y1: r.top, x2: r.right, y2: r.bottom, visible, fullyVisible: fVisibleCheck, anchorMatch, clickPoints };
73
+ }, { sel: selector, idx: index, fVisible: fullyVisible, anchorPoint: anchor });
74
+ const getTextLen = async () => ctx.page.evaluate(({ sel, idx }) => {
75
+ const nodes = Array.from(document.querySelectorAll(sel));
76
+ const root = nodes[idx];
77
+ if (!root)
78
+ return null;
79
+ const focusEl = root instanceof HTMLInputElement ||
80
+ root instanceof HTMLTextAreaElement ||
81
+ (root instanceof HTMLElement && root.isContentEditable)
82
+ ? root
83
+ : root.querySelector('input,textarea,[contenteditable="true"],[contenteditable="plaintext-only"]') ||
84
+ root;
85
+ if (focusEl instanceof HTMLInputElement || focusEl instanceof HTMLTextAreaElement)
86
+ return focusEl.value.length;
87
+ if (focusEl instanceof HTMLElement && focusEl.isContentEditable)
88
+ return (focusEl.textContent || '').trim().length;
89
+ return (focusEl.textContent || '').trim().length;
90
+ }, { sel: selector, idx: index });
91
+ const isFocused = async () => ctx.page.evaluate(({ sel, idx }) => {
92
+ const nodes = Array.from(document.querySelectorAll(sel));
93
+ const root = nodes[idx];
94
+ if (!root)
95
+ return false;
96
+ const active = document.activeElement;
97
+ if (!active)
98
+ return false;
99
+ if (!(active instanceof Element))
100
+ return false;
101
+ return root === active || root.contains(active);
102
+ }, { sel: selector, idx: index });
103
+ // 1) 定位目标元素(只读)并系统点击聚焦
104
+ const rect = await getClickableRect();
105
+ if (!rect || !rect.visible) {
106
+ return { success: false, error: 'element not visible' };
107
+ }
108
+ if (fullyVisible && !rect.fullyVisible) {
109
+ return { success: false, error: 'element not fully visible in viewport' };
110
+ }
111
+ if (anchor && !rect.anchorMatch) {
112
+ return { success: false, error: 'anchor point does not hit target element' };
113
+ }
114
+ let focused = false;
115
+ for (const p of rect.clickPoints) {
116
+ const x = Math.round(p.x);
117
+ const y = Math.round(p.y);
118
+ if (useSystemMouse) {
119
+ await ctx.systemInput.mouseClick(x, y);
120
+ }
121
+ else {
122
+ await protocolMouse.click(x, y);
123
+ }
124
+ await new Promise((r) => setTimeout(r, 160));
125
+ try {
126
+ focused = await isFocused();
127
+ }
128
+ catch {
129
+ focused = false;
130
+ }
131
+ if (focused)
132
+ break;
133
+ }
134
+ if (!focused) {
135
+ return { success: false, error: 'unable to focus element' };
136
+ }
137
+ // 2) 清空(系统级:全选 + 删除)
138
+ if (config.clear_first && typeof keyboard.press === 'function') {
139
+ // 先尽量把光标落到末尾,避免某些站点的输入框未自动聚焦导致清空失败
140
+ await keyboard.press('End').catch(() => { });
141
+ await new Promise((r) => setTimeout(r, 80));
142
+ // macOS 用 Meta+A;其他平台用 Control+A(macOS 的 Control+A 会把光标移到行首,反而破坏全选)
143
+ const isMac = process.platform === 'darwin';
144
+ if (isMac) {
145
+ await keyboard.press('Meta+A').catch(() => { });
146
+ }
147
+ else {
148
+ await keyboard.press('Control+A').catch(() => { });
149
+ }
150
+ await new Promise((r) => setTimeout(r, 80));
151
+ await keyboard.press('Backspace').catch(() => { });
152
+ await keyboard.press('Delete').catch(() => { });
153
+ await new Promise((r) => setTimeout(r, 120));
154
+ // 兜底:如果仍未清空,使用有限次 Backspace 清空(系统级)
155
+ let len = null;
156
+ try {
157
+ len = await getTextLen();
158
+ }
159
+ catch {
160
+ len = null;
161
+ }
162
+ if (typeof len === 'number' && len > 0) {
163
+ await keyboard.press('End').catch(() => { });
164
+ const maxBackspace = Math.min(80, len + 10);
165
+ for (let i = 0; i < maxBackspace; i += 1) {
166
+ await keyboard.press('Backspace').catch(() => { });
167
+ }
168
+ await new Promise((r) => setTimeout(r, 120));
169
+ }
170
+ }
171
+ // 3) 系统级输入
172
+ const delay = config.human_typing ? 80 : 0;
173
+ await keyboard.type(String(config.text ?? ''), { delay });
174
+ // 4) 提交(可选)
175
+ if (config.submit && typeof keyboard.press === 'function') {
176
+ await new Promise((r) => setTimeout(r, 200));
177
+ await keyboard.press('Enter');
178
+ }
179
+ if (config.pause_after) {
180
+ await new Promise((r) => setTimeout(r, config.pause_after));
181
+ }
182
+ return { success: true, inputMode: useSystemMouse ? 'system' : 'protocol' };
183
+ }
184
+ export const typeOperation = {
185
+ id: 'type',
186
+ description: 'Type text into input element',
187
+ requiredCapabilities: ['input'],
188
+ run: runType,
189
+ };
190
+ //# sourceMappingURL=type.js.map
@@ -0,0 +1,100 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import { getOperation } from './registry.js';
3
+ import { containerAllowsOperation } from './container-binding.js';
4
+ export class ContainerOperationQueue extends EventEmitter {
5
+ queues = new Map();
6
+ processing = new Set();
7
+ options;
8
+ taskCounter = 0;
9
+ constructor(options = {}) {
10
+ super();
11
+ this.options = { autoStart: true, ...options };
12
+ }
13
+ enqueue(container, operationId, config = {}) {
14
+ containerAllowsOperation(container, operationId);
15
+ const queue = this.ensureQueue(container.id);
16
+ const task = {
17
+ id: `${container.id}:${operationId}:${Date.now()}:${this.taskCounter++}`,
18
+ container,
19
+ operationId,
20
+ priority: config.priority ?? 0,
21
+ config: (config.config || {}),
22
+ status: 'pending',
23
+ enqueuedAt: Date.now(),
24
+ event: config.event,
25
+ };
26
+ queue.push(task);
27
+ queue.sort((a, b) => b.priority - a.priority || a.enqueuedAt - b.enqueuedAt);
28
+ this.emit('task:queued', { task });
29
+ if (this.options.autoStart) {
30
+ void this.process(container.id);
31
+ }
32
+ return task;
33
+ }
34
+ async process(containerId) {
35
+ if (this.processing.has(containerId)) {
36
+ return;
37
+ }
38
+ const queue = this.ensureQueue(containerId);
39
+ if (!queue.length) {
40
+ return;
41
+ }
42
+ this.processing.add(containerId);
43
+ try {
44
+ while (queue.length) {
45
+ const task = queue.shift();
46
+ await this.runTask(task);
47
+ }
48
+ }
49
+ finally {
50
+ this.processing.delete(containerId);
51
+ }
52
+ }
53
+ async runTask(task) {
54
+ const operation = getOperation(task.operationId);
55
+ if (!operation) {
56
+ task.status = 'failed';
57
+ task.error = `Operation ${task.operationId} not found`;
58
+ this.emit('task:failed', { task, error: task.error });
59
+ return;
60
+ }
61
+ if (!this.options.contextProvider) {
62
+ task.status = 'failed';
63
+ task.error = 'No OperationContext provider configured';
64
+ this.emit('task:failed', { task, error: task.error });
65
+ return;
66
+ }
67
+ const context = await this.options.contextProvider(task);
68
+ task.startedAt = Date.now();
69
+ task.status = 'running';
70
+ this.emit('task:started', { task });
71
+ try {
72
+ const executor = this.options.executor ?? this.defaultExecutor;
73
+ const result = await executor(task, context);
74
+ task.result = result;
75
+ task.status = 'completed';
76
+ task.finishedAt = Date.now();
77
+ this.emit('task:completed', { task, result });
78
+ }
79
+ catch (err) {
80
+ task.status = 'failed';
81
+ task.error = err?.message || String(err);
82
+ task.finishedAt = Date.now();
83
+ this.emit('task:failed', { task, error: task.error });
84
+ }
85
+ }
86
+ async defaultExecutor(task, context) {
87
+ const operation = getOperation(task.operationId);
88
+ if (!operation) {
89
+ throw new Error(`Operation ${task.operationId} not registered`);
90
+ }
91
+ return operation.run(context, task.config);
92
+ }
93
+ ensureQueue(containerId) {
94
+ if (!this.queues.has(containerId)) {
95
+ this.queues.set(containerId, []);
96
+ }
97
+ return this.queues.get(containerId);
98
+ }
99
+ }
100
+ //# sourceMappingURL=queue.js.map
@@ -0,0 +1,11 @@
1
+ const registry = new Map();
2
+ export function registerOperation(definition) {
3
+ registry.set(definition.id, definition);
4
+ }
5
+ export function getOperation(id) {
6
+ return registry.get(id);
7
+ }
8
+ export function listOperations() {
9
+ return Array.from(registry.values());
10
+ }
11
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1,33 @@
1
+ async function ensureRobot(ctx) {
2
+ if (ctx.systemInput?.mouseMove && ctx.systemInput.mouseClick) {
3
+ return ctx.systemInput;
4
+ }
5
+ // robotjs has been removed due to CI build issues on Linux
6
+ // TODO: Replace with a cross-platform alternative or implement platform-specific solutions
7
+ throw new Error('robotjs removed from dependencies. System-level mouse operations are currently unavailable.');
8
+ }
9
+ export const mouseMoveOperation = {
10
+ id: 'system:mouse-move',
11
+ description: '移动系统鼠标到屏幕坐标',
12
+ run: async (ctx, config) => {
13
+ if (typeof config.x !== 'number' || typeof config.y !== 'number') {
14
+ throw new Error('只支持全局屏幕坐标 (x,y)');
15
+ }
16
+ const sys = await ensureRobot(ctx);
17
+ await sys.mouseMove(config.x, config.y, config.steps);
18
+ return { success: true };
19
+ },
20
+ };
21
+ export const mouseClickOperation = {
22
+ id: 'system:mouse-click',
23
+ description: '在屏幕坐标点击鼠标',
24
+ run: async (ctx, config) => {
25
+ if (typeof config.x !== 'number' || typeof config.y !== 'number') {
26
+ throw new Error('只支持全局屏幕坐标 (x,y)');
27
+ }
28
+ const sys = await ensureRobot(ctx);
29
+ await sys.mouseClick(config.x, config.y, config.button, config.clicks);
30
+ return { success: true };
31
+ },
32
+ };
33
+ //# sourceMappingURL=mouse.js.map
@@ -0,0 +1,33 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import path from 'node:path';
3
+ export async function readJsonMaybe(filePath) {
4
+ try {
5
+ const raw = await fs.readFile(filePath, 'utf8');
6
+ return JSON.parse(raw);
7
+ }
8
+ catch (err) {
9
+ if (err?.code === 'ENOENT')
10
+ return null;
11
+ throw err;
12
+ }
13
+ }
14
+ export async function atomicWriteJson(filePath, data, options = {}) {
15
+ const encoding = options.encoding || 'utf8';
16
+ const dir = path.dirname(filePath);
17
+ await fs.mkdir(dir, { recursive: true });
18
+ const tmpPath = path.join(dir, `${path.basename(filePath)}.${process.pid}.${Date.now()}.tmp`);
19
+ await fs.writeFile(tmpPath, JSON.stringify(data, null, 2), encoding);
20
+ try {
21
+ await fs.rename(tmpPath, filePath);
22
+ }
23
+ catch (err) {
24
+ // Windows: rename 不允许覆盖已存在文件
25
+ if (err?.code === 'EEXIST' || err?.code === 'EPERM') {
26
+ await fs.rm(filePath, { force: true });
27
+ await fs.rename(tmpPath, filePath);
28
+ return;
29
+ }
30
+ throw err;
31
+ }
32
+ }
33
+ //# sourceMappingURL=atomic-json.js.map
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Workflow Block: AnchorVerificationBlock
3
+ *
4
+ * 职责:
5
+ * - 基于容器定义(container-library)验证指定容器锚点是否在视口内且可见
6
+ * - 支持进入锚点 / 离开锚点两种语义(enter/exit)
7
+ * - 避免在这里直接调用 containers:match,降低超时对主流程的影响
8
+ */
9
+ export async function execute(input) {
10
+ const { sessionId, containerId, operation, expectedVisible = operation === 'enter',
11
+ // timeoutMs 目前只用于 browser:execute 的防御性超时
12
+ timeoutMs = 10000, serviceUrl = 'http://127.0.0.1:7701' } = input;
13
+ try {
14
+ console.log(`[AnchorVerification] ${operation} anchor: ${containerId}`);
15
+ // 通过 container-library 定义获取 selector,并在页面内高亮 + 读取 Rect。
16
+ // 注意:这里不再调用 containers:match,避免复用阶段性 P0 问题。
17
+ const { verifyAnchorByContainerId } = await import('./helpers/containerAnchors.js');
18
+ const anchor = await verifyAnchorByContainerId(containerId, sessionId, serviceUrl, '3px solid #ff4444', 2000);
19
+ if (!anchor.found) {
20
+ return {
21
+ success: false,
22
+ verified: false,
23
+ containerFound: false,
24
+ visible: false,
25
+ error: anchor.error || `容器未找到: ${containerId}`
26
+ };
27
+ }
28
+ const rect = anchor.rect;
29
+ if (!rect) {
30
+ return {
31
+ success: false,
32
+ verified: false,
33
+ containerFound: true,
34
+ visible: false,
35
+ error: '未获取到锚点 Rect'
36
+ };
37
+ }
38
+ // 视口内判定:在这里不直接依赖 window.innerHeight,
39
+ // 仅要求宽高 > 0,由调用方结合 Rect 再做更严格判断。
40
+ const visible = rect.width > 0 && rect.height > 0;
41
+ // enter: 期望可见;exit: 期望不可见/不可命中
42
+ const verified = visible === !!expectedVisible;
43
+ if (!verified) {
44
+ return {
45
+ success: false,
46
+ verified: false,
47
+ containerFound: true,
48
+ visible,
49
+ rect,
50
+ error: `锚点验证失败: 期望${expectedVisible ? '可见' : '不可见'}, 实际${visible ? '可见' : '不可见'}`
51
+ };
52
+ }
53
+ return {
54
+ success: true,
55
+ verified: true,
56
+ containerFound: true,
57
+ visible,
58
+ rect
59
+ };
60
+ }
61
+ catch (err) {
62
+ return {
63
+ success: false,
64
+ verified: false,
65
+ containerFound: false,
66
+ visible: false,
67
+ error: `锚点验证异常: ${err.message}`
68
+ };
69
+ }
70
+ }
71
+ //# sourceMappingURL=AnchorVerificationBlock.js.map
@@ -0,0 +1,26 @@
1
+ /**
2
+ * BehaviorRandomizer - 行为随机化工具
3
+ *
4
+ * 用于降低自动化痕迹:
5
+ * - 随机延迟
6
+ * - 随机滚动偏移
7
+ * - 随机输入节奏
8
+ */
9
+ export function randomDelay(options = {}) {
10
+ const min = options.minMs ?? 300;
11
+ const max = options.maxMs ?? 1200;
12
+ const delay = Math.floor(Math.random() * (max - min + 1)) + min;
13
+ return new Promise(resolve => setTimeout(resolve, delay));
14
+ }
15
+ export function randomOffset(base, variance = 50) {
16
+ const offset = Math.floor(Math.random() * variance * 2) - variance;
17
+ return base + offset;
18
+ }
19
+ export async function typeWithDelay(text, onChar, minDelay = 50, maxDelay = 200) {
20
+ for (const char of text) {
21
+ await onChar(char);
22
+ const delay = Math.floor(Math.random() * (maxDelay - minDelay + 1)) + minDelay;
23
+ await new Promise(resolve => setTimeout(resolve, delay));
24
+ }
25
+ }
26
+ //# sourceMappingURL=BehaviorRandomizer.js.map
@@ -0,0 +1,38 @@
1
+ import { WorkflowExecutor } from './WorkflowExecutor.js';
2
+ import { getWorkflowDefinition } from '../config/workflowRegistry.js';
3
+ export async function execute(input) {
4
+ const { workflowId, context, mergeMode = 'merge', stopOnFailure = true } = input;
5
+ if (!workflowId) {
6
+ return { success: false, error: 'workflowId is required' };
7
+ }
8
+ const def = getWorkflowDefinition(workflowId);
9
+ if (!def) {
10
+ return { success: false, error: `Workflow not found: ${workflowId}` };
11
+ }
12
+ const executor = new WorkflowExecutor();
13
+ // 由上层统一注册 Block 集(这里不做默认注册),只负责执行定义
14
+ const initialContext = context || {};
15
+ const childResult = await executor.execute(def, initialContext);
16
+ if (!childResult.success && stopOnFailure) {
17
+ return {
18
+ success: false,
19
+ error: `Child workflow failed: ${workflowId}`,
20
+ childResult,
21
+ };
22
+ }
23
+ let contextPatch = {};
24
+ if (mergeMode === 'namespace') {
25
+ contextPatch = { [workflowId]: childResult };
26
+ }
27
+ else {
28
+ // merge 模式:简单暴露最后一步输出(如果存在),否则只暴露 success
29
+ const lastStep = childResult.results[childResult.results.length - 1] || {};
30
+ contextPatch = { ...lastStep };
31
+ }
32
+ return {
33
+ success: true,
34
+ childResult,
35
+ contextPatch,
36
+ };
37
+ }
38
+ //# sourceMappingURL=CallWorkflowBlock.js.map