@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,240 @@
1
+ /**
2
+ * XHS Discover Fallback Block
3
+ *
4
+ * 独立的回退 Block:当出现 shell-page(URL=/explore/<id> 但 DOM=搜索结果)时,
5
+ * 通过点击「发现」按钮重置状态,然后重新搜索以获取正确的 /search_result URL。
6
+ *
7
+ * 约束:全系统级操作(container + keyboard/mouse),禁止 goto/refresh/url 拼接。
8
+ */
9
+ import os from 'node:os';
10
+ import path from 'node:path';
11
+ import { promises as fs } from 'node:fs';
12
+ import { ContainerRegistry } from '../../../../container-registry/src/index.js';
13
+ import { execute as phase2Search } from './Phase2SearchBlock.js';
14
+ import { detectXhsCheckpoint } from '../utils/checkpoints.js';
15
+ import { controllerAction, delay } from '../utils/controllerAction.js';
16
+ function resolveDownloadRoot() {
17
+ const custom = process.env.WEBAUTO_DOWNLOAD_ROOT || process.env.WEBAUTO_DOWNLOAD_DIR;
18
+ if (custom && custom.trim())
19
+ return custom;
20
+ const home = process.env.HOME || process.env.USERPROFILE || os.homedir();
21
+ return path.join(home, '.webauto', 'download');
22
+ }
23
+ function isDebugArtifactsEnabled() {
24
+ return (process.env.WEBAUTO_DEBUG === '1' ||
25
+ process.env.WEBAUTO_DEBUG_ARTIFACTS === '1' ||
26
+ process.env.WEBAUTO_DEBUG_SCREENSHOT === '1');
27
+ }
28
+ function decodeURIComponentSafe(value) {
29
+ try {
30
+ return decodeURIComponent(value);
31
+ }
32
+ catch {
33
+ return value;
34
+ }
35
+ }
36
+ function decodeRepeated(value, maxRounds = 3) {
37
+ let current = value;
38
+ for (let i = 0; i < maxRounds; i += 1) {
39
+ const next = decodeURIComponentSafe(current);
40
+ if (next === current)
41
+ break;
42
+ current = next;
43
+ }
44
+ return current;
45
+ }
46
+ function getKeywordFromSearchUrl(searchUrl) {
47
+ try {
48
+ const url = new URL(searchUrl);
49
+ const raw = url.searchParams.get('keyword') || '';
50
+ if (raw)
51
+ return decodeRepeated(raw).trim();
52
+ }
53
+ catch {
54
+ // ignore
55
+ }
56
+ return null;
57
+ }
58
+ async function saveScreenshot(base64, env, keyword) {
59
+ if (!isDebugArtifactsEnabled())
60
+ return null;
61
+ const dir = path.join(resolveDownloadRoot(), 'xiaohongshu', env, keyword, 'discover-fallback');
62
+ await fs.mkdir(dir, { recursive: true });
63
+ const buf = Buffer.from(base64, 'base64');
64
+ const filePath = path.join(dir, `fallback-${Date.now()}.png`);
65
+ await fs.writeFile(filePath, buf);
66
+ return filePath;
67
+ }
68
+ async function saveDomDump(dom, env, keyword) {
69
+ if (!isDebugArtifactsEnabled())
70
+ return null;
71
+ const dir = path.join(resolveDownloadRoot(), 'xiaohongshu', env, keyword, 'discover-fallback');
72
+ await fs.mkdir(dir, { recursive: true });
73
+ const filePath = path.join(dir, `fallback-${Date.now()}.json`);
74
+ await fs.writeFile(filePath, JSON.stringify(dom, null, 2), 'utf8');
75
+ return filePath;
76
+ }
77
+ export async function execute(input) {
78
+ const { keyword, profile = 'xiaohongshu_fresh', unifiedApiUrl = 'http://127.0.0.1:7701', env = 'debug', } = input;
79
+ console.log(`[XhsDiscoverFallback] start keyword=${keyword} profile=${profile}`);
80
+ const registry = new ContainerRegistry();
81
+ await registry.load();
82
+ async function waitCheckpoint(maxWaitMs) {
83
+ const start = Date.now();
84
+ let last = await detectXhsCheckpoint({ sessionId: profile, serviceUrl: unifiedApiUrl });
85
+ while (Date.now() - start < maxWaitMs) {
86
+ if (last.checkpoint !== 'detail_ready' && last.checkpoint !== 'comments_ready')
87
+ return last;
88
+ await delay(500);
89
+ last = await detectXhsCheckpoint({ sessionId: profile, serviceUrl: unifiedApiUrl });
90
+ }
91
+ return last;
92
+ }
93
+ // If we are in detail/comments modal, exit first (do NOT click Discover under modal).
94
+ let checkpoint = await detectXhsCheckpoint({ sessionId: profile, serviceUrl: unifiedApiUrl });
95
+ if (checkpoint.checkpoint === 'detail_ready' || checkpoint.checkpoint === 'comments_ready') {
96
+ console.log(`[XhsDiscoverFallback] in ${checkpoint.checkpoint}, exit modal before discover`);
97
+ try {
98
+ const r = await controllerAction('container:operation', { containerId: 'xiaohongshu_detail.close_button', operationId: 'click', sessionId: profile, timeoutMs: 15000 }, unifiedApiUrl);
99
+ console.log(`[XhsDiscoverFallback] close_button click: success=${Boolean(r?.success !== false)}`);
100
+ }
101
+ catch {
102
+ console.log('[XhsDiscoverFallback] close_button click failed (ignored)');
103
+ }
104
+ checkpoint = await waitCheckpoint(8000);
105
+ if (checkpoint.checkpoint === 'detail_ready' || checkpoint.checkpoint === 'comments_ready') {
106
+ // Fallback: ESC twice
107
+ for (let i = 0; i < 2; i += 1) {
108
+ console.log(`[XhsDiscoverFallback] still in ${checkpoint.checkpoint}, press ESC (round=${i + 1})`);
109
+ await controllerAction('keyboard:press', { profileId: profile, key: 'Escape' }, unifiedApiUrl);
110
+ checkpoint = await waitCheckpoint(8000);
111
+ if (checkpoint.checkpoint !== 'detail_ready' && checkpoint.checkpoint !== 'comments_ready')
112
+ break;
113
+ }
114
+ }
115
+ // If still in detail/comments, stop (do not proceed to discover).
116
+ if (checkpoint.checkpoint === 'detail_ready' || checkpoint.checkpoint === 'comments_ready') {
117
+ let screenshotPath;
118
+ let domDumpPath;
119
+ try {
120
+ const shot = await controllerAction('browser:screenshot', { profileId: profile, fullPage: false }, unifiedApiUrl)
121
+ .then((res) => res?.data || res?.result || res?.data?.data || '');
122
+ if (typeof shot === 'string' && shot) {
123
+ const saved = await saveScreenshot(shot, env, keyword);
124
+ if (saved)
125
+ screenshotPath = saved;
126
+ }
127
+ }
128
+ catch { }
129
+ try {
130
+ const dom = await controllerAction('browser:execute', {
131
+ profile,
132
+ script: '(() => ({ url: window.location.href, title: document.title, readyState: document.readyState, text: document.body ? document.body.innerText.slice(0, 800) : "" }))()'
133
+ }, unifiedApiUrl).then((res) => res?.result || res?.data?.result || null);
134
+ if (dom) {
135
+ const saved = await saveDomDump(dom, env, keyword);
136
+ if (saved)
137
+ domDumpPath = saved;
138
+ }
139
+ }
140
+ catch { }
141
+ return {
142
+ success: false,
143
+ finalUrl: checkpoint.url || '',
144
+ finalCheckpoint: checkpoint.checkpoint,
145
+ screenshotPath,
146
+ domDumpPath,
147
+ };
148
+ }
149
+ }
150
+ const defs = registry.getContainersForUrl('https://www.xiaohongshu.com/explore/');
151
+ const discoverDef = defs?.['xiaohongshu_detail.discover_button'] || defs?.['xiaohongshu_home.discover_button'];
152
+ const selectorDefs = Array.isArray(discoverDef?.selectors) ? discoverDef.selectors : [];
153
+ const primarySelectorDef = selectorDefs.find((s) => s?.variant === 'primary') || selectorDefs[0];
154
+ const discoverSelector = String(primarySelectorDef?.css || 'a[href="/"]');
155
+ console.log(`[XhsDiscoverFallback] click discover selector=${discoverSelector}`);
156
+ let clicked = false;
157
+ // Prefer container operations (system-level) to avoid selector drift.
158
+ const candidates = [
159
+ 'xiaohongshu_home.discover_button',
160
+ 'xiaohongshu_search.discover_button',
161
+ ];
162
+ for (const id of candidates) {
163
+ try {
164
+ const r = await controllerAction('container:operation', { containerId: id, operationId: 'click', sessionId: profile, timeoutMs: 15000 }, unifiedApiUrl);
165
+ if (r?.success !== false) {
166
+ clicked = true;
167
+ console.log(`[XhsDiscoverFallback] container click ok: ${id}`);
168
+ break;
169
+ }
170
+ }
171
+ catch {
172
+ // ignore and try next
173
+ }
174
+ }
175
+ // Fallback: raw selector click (still system-level via container:click)
176
+ if (!clicked) {
177
+ for (let i = 0; i < 3; i += 1) {
178
+ const result = await controllerAction('container:click', { profileId: profile, selector: discoverSelector, highlight: true, timeoutMs: 8000 }, unifiedApiUrl).then((res) => Boolean(res?.ok ?? res?.result?.ok ?? res?.data?.ok));
179
+ if (result) {
180
+ clicked = true;
181
+ console.log('[XhsDiscoverFallback] selector click ok');
182
+ break;
183
+ }
184
+ await delay(600);
185
+ }
186
+ }
187
+ console.log(`[XhsDiscoverFallback] click discover done clicked=${clicked}`);
188
+ // Let XHS settle. Avoid refresh/goto.
189
+ await delay(2000);
190
+ // Re-run search.
191
+ const searchRes = await phase2Search({ keyword, profile, unifiedApiUrl });
192
+ const finalUrl = searchRes.finalUrl;
193
+ const finalCheckpoint = await detectXhsCheckpoint({ sessionId: profile, serviceUrl: unifiedApiUrl });
194
+ const isSearchResultPage = finalUrl.includes('/search_result') && getKeywordFromSearchUrl(finalUrl) === keyword;
195
+ const isSearchReady = finalCheckpoint.checkpoint === 'search_ready';
196
+ console.log(`[XhsDiscoverFallback] final checkpoint=${finalCheckpoint.checkpoint} url=${finalUrl}`);
197
+ if (!isSearchResultPage || !isSearchReady) {
198
+ let screenshotPath;
199
+ let domDumpPath;
200
+ try {
201
+ const shot = await controllerAction('browser:screenshot', { profileId: profile, fullPage: false }, unifiedApiUrl)
202
+ .then((res) => res?.data || res?.result || res?.data?.data || '');
203
+ if (typeof shot === 'string' && shot) {
204
+ const saved = await saveScreenshot(shot, env, keyword);
205
+ if (saved)
206
+ screenshotPath = saved;
207
+ }
208
+ }
209
+ catch {
210
+ // ignore
211
+ }
212
+ try {
213
+ const dom = await controllerAction('browser:execute', {
214
+ profile,
215
+ script: '(() => ({ url: window.location.href, title: document.title, readyState: document.readyState, text: document.body ? document.body.innerText.slice(0, 800) : "" }))()'
216
+ }, unifiedApiUrl).then((res) => res?.result || res?.data?.result || null);
217
+ if (dom) {
218
+ const saved = await saveDomDump(dom, env, keyword);
219
+ if (saved)
220
+ domDumpPath = saved;
221
+ }
222
+ }
223
+ catch {
224
+ // ignore
225
+ }
226
+ return {
227
+ success: false,
228
+ finalUrl,
229
+ finalCheckpoint: finalCheckpoint.checkpoint,
230
+ screenshotPath,
231
+ domDumpPath,
232
+ };
233
+ }
234
+ return {
235
+ success: true,
236
+ finalUrl,
237
+ finalCheckpoint: finalCheckpoint.checkpoint,
238
+ };
239
+ }
240
+ //# sourceMappingURL=XhsDiscoverFallbackBlock.js.map
@@ -0,0 +1,126 @@
1
+ function normalizeText(s, caseSensitive) {
2
+ const t = String(s || '').replace(/\s+/g, ' ').trim();
3
+ return caseSensitive ? t : t.toLowerCase();
4
+ }
5
+ function normalizeTerms(terms, caseSensitive) {
6
+ const list = Array.isArray(terms) ? terms : [];
7
+ const out = list
8
+ .map((x) => normalizeText(String(x || ''), caseSensitive))
9
+ .filter(Boolean);
10
+ return Array.from(new Set(out));
11
+ }
12
+ function termHits(text, terms) {
13
+ const hits = [];
14
+ for (const t of terms) {
15
+ if (!t)
16
+ continue;
17
+ if (text.includes(t))
18
+ hits.push(t);
19
+ }
20
+ return hits;
21
+ }
22
+ function evalExpr(text, expr, caseSensitive) {
23
+ if (!expr || typeof expr !== 'object')
24
+ return { ok: false, hits: [] };
25
+ switch (expr.op) {
26
+ case 'any': {
27
+ const terms = normalizeTerms(expr.terms, caseSensitive);
28
+ const hits = termHits(text, terms);
29
+ return { ok: hits.length > 0, hits };
30
+ }
31
+ case 'all': {
32
+ const terms = normalizeTerms(expr.terms, caseSensitive);
33
+ const hits = termHits(text, terms);
34
+ return { ok: terms.length > 0 ? hits.length === terms.length : true, hits };
35
+ }
36
+ case 'atLeast': {
37
+ const terms = normalizeTerms(expr.terms, caseSensitive);
38
+ const min = Math.max(0, Math.floor(Number(expr.min)));
39
+ const hits = termHits(text, terms);
40
+ return { ok: min <= 0 ? true : hits.length >= min, hits };
41
+ }
42
+ case 'and': {
43
+ const exprs = Array.isArray(expr.exprs) ? expr.exprs : [];
44
+ const hitsAll = [];
45
+ for (const e of exprs) {
46
+ const r = evalExpr(text, e, caseSensitive);
47
+ hitsAll.push(...r.hits);
48
+ if (!r.ok)
49
+ return { ok: false, hits: Array.from(new Set(hitsAll)) };
50
+ }
51
+ return { ok: true, hits: Array.from(new Set(hitsAll)) };
52
+ }
53
+ case 'or': {
54
+ const exprs = Array.isArray(expr.exprs) ? expr.exprs : [];
55
+ const hitsAll = [];
56
+ for (const e of exprs) {
57
+ const r = evalExpr(text, e, caseSensitive);
58
+ hitsAll.push(...r.hits);
59
+ if (r.ok)
60
+ return { ok: true, hits: Array.from(new Set(hitsAll)) };
61
+ }
62
+ return { ok: false, hits: Array.from(new Set(hitsAll)) };
63
+ }
64
+ case 'not': {
65
+ const r = evalExpr(text, expr.expr, caseSensitive);
66
+ return { ok: !r.ok, hits: r.hits };
67
+ }
68
+ default: {
69
+ const _exhaustive = expr;
70
+ return { ok: false, hits: [] };
71
+ }
72
+ }
73
+ }
74
+ export function matchCommentTextDsl(textRaw, rule) {
75
+ const caseSensitive = rule.caseSensitive === true;
76
+ const text = normalizeText(textRaw, caseSensitive);
77
+ const exclude = rule.exclude;
78
+ if (exclude) {
79
+ const r = evalExpr(text, exclude, caseSensitive);
80
+ if (r.ok) {
81
+ const hits = Array.from(new Set(r.hits));
82
+ return {
83
+ ok: false,
84
+ rejectedBy: 'exclude',
85
+ hits,
86
+ requireHits: [],
87
+ excludeHits: hits,
88
+ preferHits: [],
89
+ score: 0,
90
+ };
91
+ }
92
+ }
93
+ let requireHits = [];
94
+ if (rule.require) {
95
+ const r = evalExpr(text, rule.require, caseSensitive);
96
+ requireHits = Array.from(new Set(r.hits));
97
+ if (!r.ok) {
98
+ return {
99
+ ok: false,
100
+ rejectedBy: 'require',
101
+ hits: requireHits,
102
+ requireHits,
103
+ excludeHits: [],
104
+ preferHits: [],
105
+ score: 0,
106
+ };
107
+ }
108
+ }
109
+ let preferHits = [];
110
+ if (rule.prefer) {
111
+ const r = evalExpr(text, rule.prefer, caseSensitive);
112
+ preferHits = Array.from(new Set(r.hits));
113
+ }
114
+ const hits = Array.from(new Set([...requireHits, ...preferHits]));
115
+ // score: prefer hits first, then require hits
116
+ const score = preferHits.length * 100 + requireHits.length;
117
+ return {
118
+ ok: true,
119
+ hits,
120
+ requireHits,
121
+ excludeHits: [],
122
+ preferHits,
123
+ score,
124
+ };
125
+ }
126
+ //# sourceMappingURL=commentMatchDsl.js.map
@@ -0,0 +1,99 @@
1
+ function normalizeText(text, caseSensitive) {
2
+ const s = String(text || '').replace(/\s+/g, ' ').trim();
3
+ return caseSensitive ? s : s.toLowerCase();
4
+ }
5
+ function normalizeKeywords(list, caseSensitive) {
6
+ const arr = Array.isArray(list) ? list : [];
7
+ const out = arr
8
+ .map((x) => normalizeText(String(x || ''), caseSensitive))
9
+ .filter(Boolean);
10
+ // 轻量去重,保持稳定顺序
11
+ return Array.from(new Set(out));
12
+ }
13
+ function hits(text, keywords) {
14
+ const found = [];
15
+ for (const k of keywords) {
16
+ if (!k)
17
+ continue;
18
+ if (text.includes(k))
19
+ found.push(k);
20
+ }
21
+ return found;
22
+ }
23
+ export function matchCommentText(textRaw, rule) {
24
+ const caseSensitive = rule.caseSensitive === true;
25
+ const text = normalizeText(textRaw, caseSensitive);
26
+ const mustNot = normalizeKeywords(rule.mustNot, caseSensitive);
27
+ const must = normalizeKeywords(rule.must, caseSensitive);
28
+ const any = normalizeKeywords(rule.any, caseSensitive);
29
+ const should = normalizeKeywords(rule.should, caseSensitive);
30
+ const mustNotHits = hits(text, mustNot);
31
+ if (mustNotHits.length > 0) {
32
+ return {
33
+ ok: false,
34
+ anyHits: [],
35
+ mustHits: [],
36
+ shouldHits: [],
37
+ anyCount: 0,
38
+ shouldCount: 0,
39
+ rejectedBy: 'mustNot',
40
+ };
41
+ }
42
+ const mustHits = hits(text, must);
43
+ if (must.length > 0 && mustHits.length !== must.length) {
44
+ return {
45
+ ok: false,
46
+ anyHits: [],
47
+ mustHits,
48
+ shouldHits: [],
49
+ anyCount: 0,
50
+ shouldCount: 0,
51
+ rejectedBy: 'must',
52
+ };
53
+ }
54
+ const anyHits = hits(text, any);
55
+ const minAny = typeof rule.minAnyMatches === 'number' ? Math.max(0, Math.floor(rule.minAnyMatches)) : (any.length > 0 ? 1 : 0);
56
+ if (any.length > 0 && anyHits.length < minAny) {
57
+ return {
58
+ ok: false,
59
+ anyHits,
60
+ mustHits,
61
+ shouldHits: [],
62
+ anyCount: anyHits.length,
63
+ shouldCount: 0,
64
+ rejectedBy: 'any',
65
+ };
66
+ }
67
+ const shouldHits = hits(text, should);
68
+ const shouldCount = shouldHits.length;
69
+ if (typeof rule.minShouldMatches === 'number') {
70
+ const minShould = Math.max(0, Math.floor(rule.minShouldMatches));
71
+ if (should.length > 0 && shouldCount < minShould) {
72
+ return {
73
+ ok: false,
74
+ anyHits,
75
+ mustHits,
76
+ shouldHits,
77
+ anyCount: anyHits.length,
78
+ shouldCount,
79
+ rejectedBy: 'should',
80
+ };
81
+ }
82
+ }
83
+ return {
84
+ ok: true,
85
+ anyHits,
86
+ mustHits,
87
+ shouldHits,
88
+ anyCount: anyHits.length,
89
+ shouldCount,
90
+ };
91
+ }
92
+ export function isLegacyKeywordRule(rule) {
93
+ if (!rule || typeof rule !== 'object')
94
+ return false;
95
+ // legacy: uses any/must/mustNot/should keys
96
+ const keys = ['any', 'must', 'mustNot', 'should', 'minAnyMatches', 'minShouldMatches', 'caseSensitive'];
97
+ return keys.some((k) => Object.prototype.hasOwnProperty.call(rule, k));
98
+ }
99
+ //# sourceMappingURL=commentMatcher.js.map
@@ -0,0 +1,27 @@
1
+ import path from 'node:path';
2
+ import { promises as fs } from 'node:fs';
3
+ import { controllerAction } from '../../utils/controllerAction.js';
4
+ export function resolveHomeDir() {
5
+ const homeDir = process.env.HOME || process.env.USERPROFILE || '';
6
+ if (!homeDir)
7
+ throw new Error('无法获取用户主目录:HOME/USERPROFILE 未设置');
8
+ return homeDir;
9
+ }
10
+ export function resolveDownloadRoot() {
11
+ const custom = process.env.WEBAUTO_DOWNLOAD_ROOT || process.env.WEBAUTO_DOWNLOAD_DIR;
12
+ if (custom && String(custom).trim())
13
+ return String(custom).trim();
14
+ return path.join(resolveHomeDir(), '.webauto', 'download');
15
+ }
16
+ export async function takeScreenshotBase64(profileId, unifiedApiUrl) {
17
+ const shot = await controllerAction('browser:screenshot', { profileId, fullPage: false }, unifiedApiUrl);
18
+ const base64 = shot?.data || shot?.result || shot?.data?.data;
19
+ return typeof base64 === 'string' && base64 ? base64 : null;
20
+ }
21
+ export async function savePngBase64(base64, filePath) {
22
+ const dir = path.dirname(filePath);
23
+ await fs.mkdir(dir, { recursive: true });
24
+ await fs.writeFile(filePath, Buffer.from(base64, 'base64'));
25
+ return filePath;
26
+ }
27
+ //# sourceMappingURL=evidence.js.map
@@ -0,0 +1,42 @@
1
+ export function fnv1a32(input) {
2
+ // FNV-1a 32-bit
3
+ let hash = 0x811c9dc5;
4
+ const str = String(input || '');
5
+ for (let i = 0; i < str.length; i += 1) {
6
+ hash ^= str.charCodeAt(i);
7
+ // hash *= 16777619 (with 32-bit overflow)
8
+ hash = (hash + ((hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24))) >>> 0;
9
+ }
10
+ return hash >>> 0;
11
+ }
12
+ export function normalizeShard(spec) {
13
+ if (!spec)
14
+ return null;
15
+ const count = Math.max(1, Math.floor(Number(spec.count)));
16
+ const index = Math.max(0, Math.floor(Number(spec.index)));
17
+ if (!Number.isFinite(count) || !Number.isFinite(index))
18
+ return null;
19
+ if (count <= 1)
20
+ return null;
21
+ if (index >= count)
22
+ return null;
23
+ return { index, count, by: spec.by || 'noteId-hash' };
24
+ }
25
+ export function shardFilterByNoteIdHash(items, shard) {
26
+ const list = Array.isArray(items) ? items : [];
27
+ if (shard.count <= 1)
28
+ return list;
29
+ return list.filter((it) => {
30
+ const id = String(it?.noteId || '').trim();
31
+ if (!id)
32
+ return false;
33
+ return fnv1a32(id) % shard.count === shard.index;
34
+ });
35
+ }
36
+ export function shardFilterByIndexMod(items, shard) {
37
+ const list = Array.isArray(items) ? items : [];
38
+ if (shard.count <= 1)
39
+ return list;
40
+ return list.filter((_, idx) => idx % shard.count === shard.index);
41
+ }
42
+ //# sourceMappingURL=sharding.js.map