@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
@@ -1,291 +0,0 @@
1
- import { readFile } from 'node:fs/promises';
2
- import path from 'node:path';
3
- import { test } from 'node:test';
4
- import assert from 'node:assert/strict';
5
- import { fileURLToPath } from 'node:url';
6
-
7
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
8
- const entryPath = path.join(__dirname, 'xiaohongshu.mts');
9
- const helperPath = path.join(__dirname, 'xiaohongshu', 'helpers.mts');
10
- const layoutPath = path.join(__dirname, 'xiaohongshu', 'layout-block.mts');
11
- const accountPath = path.join(__dirname, 'xiaohongshu', 'account-flow.mts');
12
- const runPath = path.join(__dirname, 'xiaohongshu', 'run-flow.mts');
13
- const livePath = path.join(__dirname, 'xiaohongshu', 'live-stats.mts');
14
- const guidePath = path.join(__dirname, 'xiaohongshu', 'guide-browser-check.mts');
15
-
16
- async function readText(filePath: string) {
17
- return readFile(filePath, 'utf8');
18
- }
19
-
20
- async function readAll() {
21
- const [entry, helper, layout, account, run, live, guide] = await Promise.all([
22
- readText(entryPath),
23
- readText(helperPath),
24
- readText(layoutPath),
25
- readText(accountPath),
26
- readText(runPath),
27
- readText(livePath),
28
- readText(guidePath),
29
- ]);
30
- return { entry, helper, layout, account, run, live, guide, all: [entry, helper, layout, account, run, live, guide].join('\n') };
31
- }
32
-
33
- test('xiaohongshu tab keeps orchestrate modes and run script wiring after modular split', async () => {
34
- const { entry, run, layout } = await readAll();
35
- assert.match(entry, /buildXhsLayout/);
36
- assert.match(entry, /createRunFlowController/);
37
- assert.match(entry, /xhs-tile--\$\{id\}/);
38
- assert.match(layout, /phase1-phase2-unified/);
39
- assert.match(layout, /phase1-phase2/);
40
- assert.match(layout, /phase1-only/);
41
- assert.match(layout, /unified-only/);
42
- assert.match(run, /xhs-orchestrate\.mjs/);
43
- });
44
-
45
- test('xiaohongshu layout uses bento grid cards for account and operation areas', async () => {
46
- const { layout, entry } = await readAll();
47
- assert.match(layout, /xhs-bento-grid/);
48
- assert.match(layout, /accountBento/);
49
- assert.match(layout, /commentBento/);
50
- assert.match(layout, /collectBento/);
51
- assert.match(layout, /\[boardTile\.tile, likeTile\.tile, runTile\.tile, accountTile\.tile, commentTile\.tile, collectTile\.tile\]/);
52
- assert.match(entry, /xhs-guide-grid/);
53
- assert.match(entry, /xhs-guide-step/);
54
- });
55
-
56
- test('xiaohongshu layout includes shard stats board section', async () => {
57
- const { layout } = await readAll();
58
- assert.match(layout, /分片进度(合并 \+ 明细)/);
59
- assert.match(layout, /const shardStatsList = createEl\('div'/);
60
- });
61
-
62
- test('xiaohongshu module files are split and each stays under maintainable line caps', async () => {
63
- const files = [entryPath, helperPath, layoutPath, accountPath, runPath, livePath, guidePath];
64
- const lengths = await Promise.all(files.map(async (p) => String((await readText(p)).split(/\r?\n/g).length)));
65
- files.forEach((file, i) => {
66
- const lines = Number(lengths[i]);
67
- assert.ok(lines <= 800, `${path.basename(file)} has ${lines} lines`);
68
- });
69
- });
70
-
71
- test('xiaohongshu layout imports stringifyLikeRule helper used by rule chips', async () => {
72
- const { layout } = await readAll();
73
- assert.match(layout, /stringifyLikeRule/);
74
- assert.match(layout, /from '\.\/helpers\.mjs'/);
75
- });
76
-
77
- test('xiaohongshu keeps homepage toggle wiring between layout and tab orchestration', async () => {
78
- const { entry, layout } = await readAll();
79
- assert.match(layout, /homepageToggle/);
80
- assert.match(layout, /imagesToggle/);
81
- assert.match(entry, /homepageToggle/);
82
- assert.match(entry, /imagesToggle/);
83
- });
84
-
85
- test('xiaohongshu keeps preferred profile selectors and shard args', async () => {
86
- const { entry, run, layout } = await readAll();
87
- assert.match(layout, /const profilePickSel = createEl\('select'/);
88
- assert.match(layout, /const shardProfilesBox = createEl\('div'/);
89
- assert.match(entry, /getSelectedShardProfiles/);
90
- assert.match(entry, /void refreshProfileChoices\(\);/);
91
- assert.match(run, /profileArgs\.push\('--profiles', shardProfiles\.join\(','\)\)/);
92
- assert.match(run, /profileArgs\.push\('--profile', singleProfile\)/);
93
- });
94
-
95
- test('xiaohongshu history helper supports autocomplete and hotkey delete', async () => {
96
- const { helper, run } = await readAll();
97
- assert.match(helper, /INPUT_HISTORY_MAX = 10/);
98
- assert.match(helper, /bindInputHistory\(input: HTMLInputElement, key: string/);
99
- assert.match(helper, /input\.setAttribute\('list', safeId\)/);
100
- assert.match(helper, /evt\.ctrlKey && evt\.shiftKey && evt\.key === 'Backspace'/);
101
- assert.match(run, /persistHistoryFns\.forEach\(\(persist\) => persist\(\)\)/);
102
- });
103
-
104
- test('xiaohongshu persists and restores last config via helper storage', async () => {
105
- const { helper, entry } = await readAll();
106
- assert.match(helper, /XHS_LAST_CONFIG_KEY = 'webauto\.xhs\.lastConfig\.v1'/);
107
- assert.match(entry, /const persistedConfig = readLastConfig\(\);/);
108
- assert.match(entry, /writeLastConfig\(\{/);
109
- assert.match(entry, /bindLikeRulePersistence\(\{/);
110
- });
111
-
112
- test('xiaohongshu add-account flow creates profile then starts login-profile run', async () => {
113
- const { account } = await readAll();
114
- assert.match(account, /apps', 'webauto', 'entry', 'profilepool\.mjs'/);
115
- assert.match(account, /'add', kw, '--json'/);
116
- assert.match(account, /'login-profile'/);
117
- assert.match(account, /cmdRunJson/);
118
- assert.match(account, /cmdSpawn/);
119
- assert.match(account, /await refreshProfileChoices\(targetProfile\)/);
120
- });
121
-
122
- test('xiaohongshu account flow uses one fixed profile naming prefix', async () => {
123
- const { account } = await readAll();
124
- assert.match(account, /export function extractBatchBase\(_profileId: string\): string/);
125
- assert.match(account, /export function inferDefaultBatchBase\(_currentProfileId: string, _latestProfiles: string\[\]\): string/);
126
- assert.match(account, /const resolveAddBatchPrefix = \(\): string => \{\s*return XHS_DEFAULT_BATCH_KEY;/);
127
- assert.match(account, /setNavHint\(`Account IDs use fixed pattern: \$\{XHS_DEFAULT_BATCH_KEY\}-N`\);/);
128
- });
129
-
130
- test('xiaohongshu account flow auto-selects single profile in shard list', async () => {
131
- const { account } = await readAll();
132
- assert.match(account, /profiles\.length === 1 && prevSelected\.size === 0/);
133
- });
134
-
135
- test('xiaohongshu account flow deduplicates profile ids before render and audit', async () => {
136
- const { account } = await readAll();
137
- assert.match(account, /const uniqueProfileIds = \(items: string\[\]\) => \{/);
138
- assert.match(account, /const isNewFormatProfileId = \(id: string\) => \/\.\+-batch-\\d\+\$\/\.test/);
139
- assert.match(account, /let refreshSeq = 0;/);
140
- assert.match(account, /const seq = \+\+refreshSeq;/);
141
- assert.match(account, /if \(seq !== refreshSeq\) return;/);
142
- assert.match(account, /const profiles: string\[\] = uniqueProfileIds\(entries\.map/);
143
- assert.match(account, /filter\(isNewFormatProfileId\)/);
144
- assert.match(account, /const uniqueProfiles = uniqueProfileIds\(profiles\);/);
145
- });
146
-
147
- test('xiaohongshu consumes preflight navigation target and checks browser with runJson when available', async () => {
148
- const { entry, guide } = await readAll();
149
- assert.match(entry, /consumeNavTarget/);
150
- assert.match(entry, /runGuideBrowserCheck/);
151
- assert.match(guide, /XHS_NAV_TARGET_KEY/);
152
- assert.match(guide, /'--check-browser-only'/);
153
- assert.match(guide, /cmdRunJson/);
154
- });
155
-
156
- test('xiaohongshu account check uses browser-status probe without confirm dialog', async () => {
157
- const { entry } = await readAll();
158
- assert.match(entry, /browser-status\.mjs/);
159
- assert.match(entry, /const runBrowserStatusCheck = async/);
160
- assert.doesNotMatch(entry, /window\.confirm/);
161
- });
162
-
163
- test('xiaohongshu live stats combines cmd-event and state-update streams', async () => {
164
- const { live } = await readAll();
165
- assert.match(live, /state\+cmd-event/);
166
- assert.doesNotMatch(live, /fsReadTextTail/);
167
- assert.match(live, /const activeRunIds = new Set<string>\(\);/);
168
- assert.match(live, /window\.api\?\.onStateUpdate/);
169
- assert.match(live, /noteProgressMatch/);
170
- });
171
-
172
- test('xiaohongshu run flow forwards ocr command and gate/reply guard', async () => {
173
- const { run, entry } = await readAll();
174
- assert.match(run, /if \(unifiedEnabled && replyToggle\.checked && !gateToggle\.checked\)/);
175
- assert.match(run, /jumpToAccountSetup\(\)/);
176
- assert.match(run, /jumpToKeywordSetup\(\)/);
177
- assert.match(run, /--no-dry-run/);
178
- assert.match(run, /\[ui-run-flags\] dryRun=\$\{dryRunCheckbox\.checked\} doLikes=\$\{likesToggle\.checked\}/);
179
- assert.match(run, /--do-ocr/);
180
- assert.match(run, /--ocr-command/);
181
- assert.match(run, /--match-keywords/);
182
- assert.match(entry, /focusAccountSetup/);
183
- assert.match(entry, /focusKeywordSetup/);
184
- });
185
-
186
-
187
- test('xiaohongshu run flow keeps logs shortcut in action row', async () => {
188
- const { run } = await readAll();
189
- assert.match(run, /const logsBtn = createEl\('button', \{ type: 'button', className: 'secondary' \}, \['日志'\]\)/);
190
- assert.match(run, /api\.setActiveTab\('logs'\)/);
191
- assert.match(run, /setExpectedLinksTarget\(/);
192
- });
193
-
194
- test('xiaohongshu live stats parser accepts rotated events files and phase2 progress lines', async () => {
195
- const { live } = await readAll();
196
- assert.match(live, /setExpectedLinksTarget: \(target: number\) => void/);
197
- assert.ok(live.includes('run-events(?:'));
198
- assert.ok(live.includes('Phase2Collect(?:Links)?'));
199
- assert.ok(live.includes('liveStats.linksTarget = Math.max(liveStats.linksTarget, target);'));
200
- assert.ok(live.includes('Like Gate:'));
201
- assert.ok(live.includes("const readToken = (key: string) =>"));
202
- assert.ok(live.includes("const ruleHits = readToken('ruleHits');"));
203
- assert.ok(live.includes("const dedupSkipped = readToken('dedup');"));
204
- assert.ok(live.includes("const alreadyLikedSkipped = readToken('alreadyLiked');"));
205
- assert.ok(live.includes("const newLikes = readToken('newLikes');"));
206
- assert.ok(live.includes("const likedTotalMatch = text.match(/likedTotal=(\\d+)\\s*\\/\\s*(\\d+)/i);"));
207
- });
208
-
209
- test('xiaohongshu live stats surfaces phase2 block and fatal reasons on board', async () => {
210
- const { live } = await readAll();
211
- assert.match(live, /Rigid gate blocked click index=/);
212
- assert.match(live, /阻断原因:/);
213
- assert.match(live, /Post-click gate FAILED/);
214
- assert.match(live, /Click strategy failed:/);
215
- assert.match(live, /Click strategy no-open:/);
216
- assert.match(live, /Phase\\s\*2\\s\*失败/);
217
- });
218
-
219
- test('xiaohongshu layout and live stats include like-skip metrics', async () => {
220
- const { layout, entry, live } = await readAll();
221
- assert.match(layout, /点赞跳过:0/);
222
- assert.match(layout, /likesSkipStat/);
223
- assert.match(entry, /likesSkipStat/);
224
- assert.match(live, /点赞跳过:\$\{merged\.likesSkippedTotal\}/);
225
- assert.match(live, /跳过明细:去重/);
226
- });
227
-
228
- test('xiaohongshu guide account step always brings account tile into view before checks', async () => {
229
- const { entry } = await readAll();
230
- assert.match(entry, /accountStep\.onclick = \(\) => \{ focusTile\('account'\); void runInteractiveAccountCheck\(\); \};/);
231
- });
232
-
233
-
234
- test('xiaohongshu browser guide checks browser only once at startup', async () => {
235
- const { entry } = await readAll();
236
- assert.match(entry, /let startupBrowserChecked = false;/);
237
- assert.match(entry, /let startupBrowserCheckDone = false;/);
238
- assert.match(entry, /let browserCheckAttempted = false;/);
239
- assert.match(entry, /if \(startupBrowserChecked\) return void finalizeGuide\(\);/);
240
- assert.match(entry, /if \(browserCheckAttempted \|\| startupBrowserCheckDone \|\| guideState\.browserReady\) return;/);
241
- assert.match(entry, /startupBrowserCheckDone = true;/);
242
- assert.match(entry, /startupBrowserChecked = true;/);
243
- });
244
-
245
- test('xiaohongshu guide does not hard-block run button when not ready', async () => {
246
- const { entry } = await readAll();
247
- assert.match(entry, /guideCard\.style\.display = allReady \? 'none' : '';/);
248
- assert.match(entry, /startRunBtn\.textContent = '仍然开始运行';/);
249
- assert.match(entry, /if \(!runBtn\.disabled\) \{\s*runBtn\.title = allReady \? '' : '引导未完成,仍可直接运行';/);
250
- });
251
-
252
- test('xiaohongshu run flow only consumes stdout/stderr from current run id', async () => {
253
- const { run } = await readAll();
254
- assert.match(run, /if \(!localRunId\) return;/);
255
- assert.match(run, /if \(evtRunId && evtRunId !== localRunId\) return;/);
256
- });
257
-
258
- test('xiaohongshu run flow resets board before binding run id and keeps live-stats subscription after exit', async () => {
259
- const { run } = await readAll();
260
- assert.match(run, /liveStats\.resetLiveStats\(\);\s*liveStats\.setActiveRunId\(localRunId\);/);
261
- assert.match(run, /if \(runMode !== 'phase1-only' && Number\.isFinite\(targetNum\) && targetNum > 0\) \{\s*liveStats\.setExpectedLinksTarget\(targetNum\);/);
262
- assert.match(run, /if \(eventType === 'exit'\) \{\s*const exitedRunId = localRunId;/);
263
- assert.match(run, /liveStats\.parseStdoutForEvents\(\s*`\[rid:\$\{evtRunId \|\| localRunId\}\] \[exit\] code=\$\{evt\?\.exitCode \?\? 'null'\} signal=\$\{evt\?\.signal \?\? 'null'\}`,/);
264
- assert.match(run, /void recoverRunFromStateTasks\(\)\.then\(\(restored\) => \{\s*if \(!restored \|\| restored === exitedRunId\) setRunningUi\(false\);/);
265
- assert.doesNotMatch(run, /if \(eventType === 'exit'\) \{\s*liveStats\.dispose\(\);/);
266
- });
267
-
268
- test('xiaohongshu run flow restores running runId after tab re-entry and updates run button label', async () => {
269
- const { run } = await readAll();
270
- assert.match(run, /const resolveRunningXhsRunId = \(\) => \{/);
271
- assert.match(run, /const restoredRunId = resolveRunningXhsRunId\(\);/);
272
- assert.match(run, /runBtn\.textContent = running \? '编排运行中\.\.\.' : '开始执行编排';/);
273
- assert.match(run, /runBtn\.disabled = running/);
274
- });
275
-
276
- test('xiaohongshu live stats accepts prefixed rid and allows progress\/stats updates from related run ids', async () => {
277
- const { live } = await readAll();
278
- assert.match(live, /const prefixedRid = rawText\.match\(\/\^\\\[rid:/);
279
- assert.match(live, /运行账号 \$\{shardItems\.length\} · 运行中 \$\{runningCount\} · 异常 \$\{errorCount\}/);
280
- assert.match(live, /阶段 \$\{item\.phase \|\| '未知'\} · 状态 \$\{statusLabel\(item\)\} · 动作 \$\{item\.action \|\| '等待日志'\}/);
281
- assert.match(live, /异常:\$\{item\.anomaly\}/);
282
- assert.match(live, /const looksProgress =/);
283
- assert.match(live, /const looksStats =/);
284
- assert.match(live, /if \(activeRunIds\.size > 0 && !activeRunIds\.has\(rid\) && !\(looksProgress \|\| looksStats\)\) return;/);
285
- assert.match(live, /const t = String\(update\?\.type \|\| ''\)\.trim\(\);/);
286
- assert.match(live, /if \(t === 'progress'\) \{\s*applyStatePatch\(\{ progress: patch \}, rid\);/);
287
- assert.match(live, /else if \(t === 'stats'\) \{\s*applyStatePatch\(\{ stats: patch \}, rid\);/);
288
- assert.match(live, /const shardStats = new Map<string, ShardProgress>\(\);/);
289
- assert.match(live, /const renderShardStats = \(\) => \{/);
290
- assert.match(live, /setShardProfiles: \(profiles: string\[\]\) => void/);
291
- });
@@ -1,31 +0,0 @@
1
- export function createEl<K extends keyof HTMLElementTagNameMap>(
2
- tag: K,
3
- props: Partial<HTMLElementTagNameMap[K]> & Record<string, any> = {},
4
- children: Array<HTMLElement | string> = [],
5
- ): HTMLElementTagNameMap[K] {
6
- const el = document.createElement(tag);
7
- for (const [k, v] of Object.entries(props)) {
8
- // @ts-ignore
9
- el[k] = v;
10
- }
11
- for (const c of children) {
12
- if (typeof c === 'string') el.appendChild(document.createTextNode(c));
13
- else el.appendChild(c);
14
- }
15
- return el;
16
- }
17
-
18
- export function labeledInput(label: string, input: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement) {
19
- // Avoid forcing wide min-width so toolbars can fit on smaller windows.
20
- const wrap = createEl('div', { style: 'display:flex; flex-direction:column; gap:6px; min-width:140px; max-width:260px;' });
21
- wrap.appendChild(createEl('label', {}, [label]));
22
- wrap.appendChild(input);
23
- return wrap;
24
- }
25
-
26
- export function section(title: string, children: HTMLElement[]) {
27
- const card = createEl('div', { className: 'card' });
28
- card.appendChild(createEl('div', { style: 'font-weight:700; margin-bottom:10px;' }, [title]));
29
- children.forEach((c) => card.appendChild(c));
30
- return card;
31
- }
@@ -1,141 +0,0 @@
1
- # Camoufox 中文配置指南
2
-
3
- ## 问题解决
4
-
5
- 经过多次测试,发现 Camoufox 中文乱码问题的根源是配置过于复杂。正确的解决方案是使用最小化但有效的配置。
6
-
7
- ## 核心配置
8
-
9
- **成功的配置只需要两个参数:**
10
-
11
- ```python
12
- {
13
- 'locale': 'zh-CN', # 设置浏览器语言环境
14
- 'args': ['--lang=zh-CN'] # 设置浏览器语言
15
- }
16
- ```
17
-
18
- ## 使用方法
19
-
20
- ### 方式1:函数式(推荐)
21
-
22
- ```python
23
- from camoufox_final_setup import launch_camoufox_chinese
24
-
25
- # 启动浏览器
26
- playwright, browser = launch_camoufox_chinese(headless=False)
27
-
28
- try:
29
- page = browser.new_page()
30
- page.goto('https://www.baidu.com')
31
- print(page.title()) # 输出:百度一下,你就知道
32
- finally:
33
- browser.close()
34
- playwright.stop()
35
- ```
36
-
37
- ### 方式2:类式(自动管理资源)
38
-
39
- ```python
40
- from camoufox_final_setup import CamoufoxChineseBrowser
41
-
42
- # 使用上下文管理器
43
- with CamoufoxChineseBrowser(headless=False) as browser:
44
- page = browser.new_page()
45
- page.goto('https://www.baidu.com')
46
- print(page.title())
47
- ```
48
-
49
- ### 方式3:快速测试
50
-
51
- ```python
52
- from camoufox_final_setup import CamoufoxChineseBrowser
53
-
54
- browser = CamoufoxChineseBrowser(headless=False)
55
- browser.start()
56
- try:
57
- browser.quick_test('https://www.baidu.com', wait_time=3)
58
- finally:
59
- browser.stop()
60
- ```
61
-
62
- ## 配置文件说明
63
-
64
- - `camoufox_final_setup.py` - **最终版本**,使用最小化有效配置
65
- - `camoufox_minimal_chinese.py` - 最小化配置测试版本
66
- - `camoufox_chinese_setup.py` - 早期版本(配置过于复杂)
67
- - `camoufox_browser.py` - 功能完整但配置复杂的版本
68
-
69
- ## 关键发现
70
-
71
- 1. **最小配置原则**:只需要 `locale='zh-CN'` 和 `args=['--lang=zh-CN']`
72
- 2. **避免过度配置**:过多的参数可能导致冲突
73
- 3. **系统字体支持**:macOS 系统自带中文字体支持良好
74
- 4. **UTF-8 自动处理**:浏览器会自动处理 UTF-8 编码
75
-
76
- ## 测试结果验证
77
-
78
- 成功的测试输出:
79
- ```
80
- 页面标题: 百度一下,你就知道
81
- 字符集: UTF-8, 语言: zh-CN
82
- ```
83
-
84
- ## 注意事项
85
-
86
- - 确保系统有中文字体支持(macOS 默认支持)
87
- - 避免添加不必要的参数
88
- - 使用 `with` 语句确保资源正确释放
89
- - 无头模式设置 `headless=True`
90
-
91
- ## 故障排除
92
-
93
- 如果仍有问题:
94
- 1. 检查系统字体:`fc-list :lang=zh`
95
- 2. 测试其他中文网站
96
- 3. 确认使用的是 `camoufox_final_setup.py` 中的配置
97
-
98
- ## 高级问题:中文变成「口口口」方框
99
-
100
- 在部分版本的 Camoufox 中,浏览器会通过指纹系统动态修改字体列表(`update_fonts`),某些随机组合可能会 **去掉 CJK 字体**,导致页面编码是 UTF-8,标题也是中文,但页面上所有汉字渲染成「口口口」方框。
101
-
102
- ### 现象特征
103
-
104
- - `document.characterSet == 'UTF-8'`
105
- - `page.title()` 输出正常中文
106
- - 页面绝大部分正文/链接文字显示为方框(尤其是百度首页)
107
-
108
- ### WebAuto 中的解决方案
109
-
110
- 在 `browser_interface.py` 中已经内置了专门的修复逻辑:
111
-
112
- - 启动时:
113
- - 禁用 Camoufox 默认扩展下载与路径校验;
114
- - Monkey patch `camoufox.utils.update_fonts`,**不再改动系统字体列表**,避免指纹算法把中文字体移除。
115
- - 页面级别:
116
- - 在每次 `goto()` 后注入一段 CSS,强制使用常见中文字体栈:
117
-
118
- ```python
119
- html, body, * {
120
- font-family: "PingFang SC", "Microsoft YaHei", "SimHei",
121
- system-ui, -apple-system, BlinkMacSystemFont,
122
- sans-serif !important;
123
- }
124
- ```
125
-
126
- 只要通过统一入口使用浏览器,即可自动避开字体指纹带来的中文方框问题:
127
-
128
- ```python
129
- from browser_interface import create_browser
130
-
131
- with create_browser({'headless': False}) as browser:
132
- page = browser.new_page()
133
- page.goto('https://www.baidu.com')
134
- print(page.title())
135
- ```
136
-
137
- ### 使用建议
138
-
139
- - **不要** 在业务代码里直接调用 `camoufox.launch_options` / `update_fonts` / `custom_fonts_only` 等底层 API。
140
- - 始终通过 `browser_interface.create_browser` 创建 Camoufox 实例,让字体与语言配置由统一入口托管。
141
- - 如遇到旧 profile 仍然出现方框,可尝试关闭所有 Camoufox 进程后使用全新 profile 再次启动。
package/docs/USAGE_V3.md DELETED
@@ -1,163 +0,0 @@
1
- # 小红书采集工具 v3 - 快速使用指南
2
-
3
- ## 🚀 版本说明
4
-
5
- **v3.0.0** 是统一入口版本,整合了 Phase1、Phase2 和 Phase34 三个阶段,提供更简单的使用体验。
6
-
7
- ## 📦 安装包结构
8
-
9
- ```
10
- xiaohongshu-collector/
11
- ├── bin/
12
- │ ├── xhs-cli # Unix/Linux 入口
13
- │ └── xhs-cli.bat # Windows 入口
14
- ├── scripts/
15
- │ └── run-xiaohongshu-phase1-2-34-v3.mjs # v3 核心脚本
16
- ├── README.md
17
- ├── install.sh # Unix 安装脚本
18
- ├── install.bat # Windows 安装脚本
19
- └── package.json
20
- ```
21
-
22
- ## 🎯 快速开始
23
-
24
- ### 1. 安装依赖
25
-
26
- ```bash
27
- # macOS/Linux
28
- ./install.sh
29
-
30
- # Windows
31
- install.bat
32
- ```
33
-
34
- ### 2. 使用 v3 统一入口(推荐)
35
-
36
- **一键完整运行:**
37
- ```bash
38
- # macOS/Linux
39
- ./bin/xhs-cli v3 --keyword "手机壳" --count 50 --env prod
40
-
41
- # Windows
42
- bin\xhs-cli.bat v3 --keyword "手机壳" --count 50 --env prod
43
- ```
44
-
45
- **查看帮助:**
46
- ```bash
47
- ./bin/xhs-cli v3 --help
48
- ```
49
-
50
- **查看版本:**
51
- ```bash
52
- ./bin/xhs-cli v3 --version
53
- ```
54
-
55
- ## 🔧 高级用法
56
-
57
- ### 分阶段执行
58
-
59
- v3 支持灵活的阶段控制:
60
-
61
- **仅运行 Phase1(登录):**
62
- ```bash
63
- ./bin/xhs-cli v3 --keyword "测试" --stopAfter phase1
64
- ```
65
-
66
- **从 Phase34 开始(跳过搜索):**
67
- ```bash
68
- ./bin/xhs-cli v3 --keyword "测试" --startAt phase34 --count 20
69
- ```
70
-
71
- **只运行 Phase2(采集链接):**
72
- ```bash
73
- ./bin/xhs-cli v3 --keyword "测试" --startAt phase2 --stopAfter phase2
74
- ```
75
-
76
- ### 完整参数列表
77
-
78
- | 参数 | 说明 | 默认值 |
79
- |------|------|--------|
80
- | `--keyword` | 搜索关键词(必填) | - |
81
- | `--count` | 目标采集数量 | 20 |
82
- | `--sessionId` | 会话ID | xiaohongshu_fresh |
83
- | `--startAt` | 起始阶段 (phase1/phase2/phase34) | phase1 |
84
- | `--stopAfter` | 结束阶段 (phase1/phase2/phase34) | phase34 |
85
- | `--linksCount` | Phase2 链接目标数 | max(count*2, count+30) |
86
- | `--env` | 运行环境 | debug |
87
- | `--version, -v` | 显示版本信息 | - |
88
- | `--help, -h` | 显示帮助信息 | - |
89
-
90
- ## 📂 数据存储位置
91
-
92
- 采集结果保存在:
93
- ```
94
- ~/.webauto/download/xiaohongshu/{env}/{keyword}/
95
- ```
96
-
97
- 例如:
98
- ```
99
- ~/.webauto/download/xiaohongshu/prod/手机壳/
100
- ├── phase2-links.jsonl # Phase2 采集的链接
101
- ├── notes/ # Phase34 采集的笔记详情
102
- │ ├── note_001.json
103
- │ ├── note_002.json
104
- │ └── ...
105
- └── organized/ # 整理后的数据
106
- ```
107
-
108
- ## ⚠️ 注意事项
109
-
110
- 1. **Node.js 版本**:需要 Node.js >= 22.0.0
111
- 2. **频率控制**:Phase2 会触发站内搜索,频繁运行可能触发风控
112
- 3. **迭代调试建议**:
113
- - Phase1 运行一次(登录)
114
- - Phase2 运行一次(采集链接)
115
- - Phase34 反复运行(采集详情)
116
- 4. **端口占用**:确保以下端口未被占用:7701, 7704, 8765, 7790
117
-
118
- ## 🐛 故障排除
119
-
120
- ### 问题:Node.js 版本过低
121
- ```bash
122
- # 查看当前版本
123
- node -v
124
-
125
- # 升级 Node.js
126
- # macOS
127
- brew install node
128
-
129
- # Windows
130
- # 访问 https://nodejs.org/ 下载安装
131
- ```
132
-
133
- ### 问题:缺少构建产物
134
- ```bash
135
- # 错误信息:❌ 缺少必要的构建产物
136
-
137
- # 解决方案:重新安装
138
- ./install.sh # 或 install.bat
139
- ```
140
-
141
- ### 问题:崩溃信息
142
- 查看崩溃日志:
143
- ```bash
144
- cat ~/.webauto/logs/crash-state.json
145
- ```
146
-
147
- ## 📞 技术支持
148
-
149
- - **GitHub**: https://github.com/your-repo/webauto
150
- - **文档**: https://github.com/your-repo/webauto/docs
151
- - **Issues**: https://github.com/your-repo/webauto/issues
152
-
153
- ## 📝 更新日志
154
-
155
- ### v3.0.0 (2026-01-22)
156
- - ✨ 统一 Phase1-2-34 入口
157
- - ✨ 添加版本管理和环境检查
158
- - ✨ 增强错误处理和崩溃恢复
159
- - ✨ 支持 Linux 平台
160
- - ✨ 改进帮助文档(中文)
161
- - ✨ 添加 SIGINT/SIGTERM 优雅退出
162
- - 🐛 修复路径检查问题
163
- - 📚 完善使用文档
@@ -1,39 +0,0 @@
1
- # macOS OCR 插件(Vision)
2
-
3
- ## 目的
4
-
5
- 在开发/守护进程(daemon)模式下,将 OCR 作为 **独立的 macOS 插件二进制** 执行,避免把 OCR 逻辑耦合在 Node 依赖或第三方 OCR 运行时里。
6
-
7
- ## 构建与安装
8
-
9
- 构建(产物写入仓库 `dist/`):
10
-
11
- ```bash
12
- npm run build:ocr:macos
13
- ```
14
-
15
- 安装到用户目录(推荐,运行时默认会优先从这里查找):
16
-
17
- ```bash
18
- node scripts/build/build-ocr-macos.mjs --install
19
- ```
20
-
21
- 安装后位置:
22
-
23
- - `~/.webauto/bin/webauto-ocr-macos`
24
-
25
- 也可以通过环境变量指定路径:
26
-
27
- - `WEBAUTO_OCR_BIN=/absolute/path/to/webauto-ocr-macos`
28
-
29
- ## 运行示例
30
-
31
- ```bash
32
- ./dist/plugins/ocr-macos/webauto-ocr-macos --json --langs "chi_sim+eng" /path/to/image.jpg
33
- ```
34
-
35
- 说明:
36
-
37
- - `--langs` 支持 `chi_sim+eng`(会映射为 Vision 的 `zh-Hans,en-US`)
38
- - 输出为 JSON 数组:`[{ image, text?, error? }]`
39
-