--- name: xianyu-hunter-monitor description: Use when BOSS asks to monitor, search, filter, analyze, or follow up on 闲鱼/goofish products through the Disrush/xianyu-hunter Playwright-based assistant. Covers setup, login, API config, safe monitoring mode, task creation, result inspection, and operational limits. version: 1.0.0 author: Hermes Agent license: MIT metadata: hermes: tags: [xianyu, goofish, monitoring, shopping, playwright, automation] related_skills: [github-repo-management, goofish-monitor-deploy, systematic-debugging] --- # Xianyu Hunter Monitor ## Overview `Disrush/xianyu-hunter` is a Node.js + Playwright web automation project for 闲鱼/Goofish. The local BOSS fork now runs in **Hermes analysis mode**: the web app only searches product pages, extracts product cards/details, and performs lightweight local prefiltering. It does **not** require configuring an AI API inside the project, and it does **not** contact sellers or run the upstream auto-chat stage. For BOSS, use this skill in **Hermes-controlled collection + analysis mode**: Hermes should operate the CLI directly (login/check/create/run/report/schedule) and treat the Web UI as a backup inspection channel only. Run modest searches, collect candidate listings into `data/tasks.json`, then analyze/summarize candidates from Hermes (or generate a Markdown report with `tools/hermes_report.mjs`). Session-specific implementation notes for the Hermes-main-control refactor are stored in `references/hermes-main-control-refactor-2026-05.md`. LAN dashboard login button and stale port/PID restart notes are stored in `references/web-login-lan-and-kill-stale-server-2026-05.md`. Local working clone established during analysis: ```bash /Users/chick/.Hermes/workspace/research/xianyu-hunter ``` The analyzed revision was `de268ba` (`feat: 消息监听从 DOM 轮询改造为 WebSocket 实时推送 + DOM 补漏`). ## When to Use Use this skill when the user asks to: - 监测闲鱼商品、扫货、蹲商品、查低价、找二手货。 - Analyze 闲鱼 listings against criteria such as price, condition, location, personal seller, warranty, battery health, etc. - Run or configure `xianyu-hunter` / `闲鱼扫货助手` / `goofish.com` automation. - Inspect previous xianyu-hunter task results under its `data/tasks.json`. - Decide whether to contact sellers based on filtered candidates. Do **not** use this skill for: - Generic price research that does not involve 闲鱼/goofish. - High-frequency scraping or bulk automated messaging. - Any action that commits BOSS to a purchase, payment, or binding offer. ## Important Safety / Consent Rules 1. **Default to analysis-only.** Do not start auto-chat unless BOSS explicitly asks to contact sellers. 2. **No purchase commitments.** Never authorize payment, deposits, order creation, or final purchase via automation. 3. **Respect account risk.** The project uses a real browser and randomized delays, but 闲鱼 may still show captcha, rate-limit, or penalize automation. Keep pages/tasks modest. 4. **Manual captcha/login.** Login and verification must be completed by the user in the visible Chromium window. 5. **Protect secrets.** API key is stored locally at `data/config.json`; never print it. If inspecting config, redact as `[REDACTED]`. 6. **Do not hide automation risk.** Tell BOSS when a run may trigger platform verification or account risk. ## Project Anatomy Key files: - `server.mjs` — Express + WebSocket dashboard, listens on `PORT` or `3000`. - `lib/browser.mjs` — Playwright persistent Chromium profile at `browser-data`, `headless: false`. - `lib/login.mjs` — opens `https://www.goofish.com/` and checks login state. - `lib/search.mjs` — searches `https://www.goofish.com/search?q=...`, applies filters, scrapes cards. - `lib/filter.mjs` — opens detail pages and performs LLM fine filtering. - `lib/chat.mjs` — optional seller chat engine, message extraction, WebSocket monitoring. - `lib/ai.mjs` — OpenAI-compatible `/chat/completions` calls and prompts. - `lib/config.mjs` — provider/model/API key config persisted to `data/config.json`. - `data/tasks.json` — task state, candidate products, logs, chat sessions. Runtime data: - `browser-data/` stores Chromium login/session state. - `data/config.json` stores AI provider config. - `data/tasks.json` stores task progress/results. ## First-Time Setup From the local clone: ```bash cd /Users/chick/.Hermes/workspace/research/xianyu-hunter npm install npx playwright install chromium ``` Start the dashboard: ```bash cd /Users/chick/.Hermes/workspace/research/xianyu-hunter PORT=3000 npm start ``` Open locally or from LAN: ```text http://localhost:3000 http://192.168.2.69:3000 ``` Then: 1. Start the dashboard; no AI/API settings are needed in the web UI. 2. Use the Web UI button **打开闲鱼登录窗口** to trigger the Mac desktop Chromium login window, or run `node tools/xianyu_ops.mjs login` from the repo. 3. Complete QR/captcha/login through macOS remote desktop/screen sharing in the spawned Chromium window. The Web UI does not embed the Goofish login page. 4. If captcha/slider appears, BOSS must complete it manually. ## Recommended Monitoring-Only Task Parameters Use restrained defaults: - `maxPages`: 1–3 initially. - `personalSeller`: true when searching high-scam/high-noise categories. - `region`: set if local pickup matters. - `priceMin`/`priceMax`: use broad but reasonable bounds. - Requirements should include risk criteria, e.g. “只看国行、自用、无拆修、成色好;排除维修/配件/求购/商家批量”。 Preferred prompts for monitoring mode: ```text coarsePrompt: 你是闲鱼商品监测助手。只做标题相关性初筛,目标是帮用户发现值得进一步分析的候选商品。只有标题与需求明确矛盾、明显是配件/维修/求购/租赁/广告时才排除;拿不准必须保留。返回纯JSON数组。 finePrompt: 你是闲鱼商品风险分析助手。根据商品详情判断是否值得用户人工查看。只做监测分析,不要鼓励自动联系卖家。优先识别:型号/规格不符、价格异常、疑似商家批量、维修/配件/求购、描述矛盾、成色/保修/拆修风险。拿不准可以通过,但理由必须提示待人工确认。返回JSON:{"pass": true/false, "reason": "简短理由,包含关键风险或亮点"} ``` ## Hermes CLI Control Flow Preferred operation is through the unified CLI wrapper; the Web dashboard is only a backup view. ```bash cd /Users/chick/.Hermes/workspace/research/xianyu-hunter # Check/start/stop background local service node tools/xianyu_ops.mjs status --port 3000 node tools/xianyu_ops.mjs start --port 3000 node tools/xianyu_ops.mjs stop # Open persistent Chromium and let BOSS/Hermes check login state node tools/xianyu_ops.mjs login # If the dashboard lacks a login button, add a POST route that calls checkLogin() # and a header button labelled “打开闲鱼登录窗口”; then restart the exact PID # listening on port 3000 (the CLI stop command may lose its .runtime state). # Create task only node tools/xianyu_ops.mjs create \ --name 'Mac mini M4 监测' \ --queries 'Mac mini M4,macmini m4' \ --price-max 3300 \ --region 成都 \ --pages 2 \ --requirements '自用,国行,成色好,无拆修,预算3300以内;排除维修/配件/求购/商家批量' # Full run: ensure service, create task, wait for completion, generate report node tools/xianyu_ops.mjs run \ --name 'Mac mini M4 监测' \ --queries 'Mac mini M4,macmini m4' \ --price-max 3300 \ --region 成都 \ --pages 2 \ --requirements '自用,国行,成色好,无拆修,预算3300以内;排除维修/配件/求购/商家批量' \ --limit 30 ``` The CLI starts the local service if needed, never requires project AI configuration, and never contacts sellers. ## Creating a Task via API API/helper usage remains available for compatibility, but prefer `tools/xianyu_ops.mjs` above. The local fork starts collection immediately and does not require AI configuration. ### Helper script A helper script was added to the local clone: ```bash cd /Users/chick/.Hermes/workspace/research/xianyu-hunter node tools/create_monitor_task.mjs \ --name 'Mac mini M4 监测' \ --queries 'Mac mini M4,macmini m4' \ --price-max 3300 \ --region 成都 \ --pages 2 \ --requirements '自用,国行,成色好,无拆修,预算3300以内;排除维修/配件/求购/商家批量;只做筛选分析,不自动联系卖家' ``` Environment override: ```bash XIANHU_BASE_URL=http://127.0.0.1:3000 node tools/create_monitor_task.mjs ... ``` ### Raw API ```bash curl -sS http://127.0.0.1:3000/api/tasks \ -H 'Content-Type: application/json' \ -d '{ "name":"Mac mini M4 监测", "queries":["Mac mini M4","macmini m4"], "priceMin":null, "priceMax":3300, "region":"成都", "personalSeller":true, "maxPages":2, "customRequirements":"自用,国行,成色好,无拆修,预算3300以内;排除维修/配件/求购/商家批量;只做筛选分析,不自动联系卖家", "coarsePrompt":"你是闲鱼商品监测助手。只做标题相关性初筛,目标是帮用户发现值得进一步分析的候选商品。只有标题与需求明确矛盾、明显是配件/维修/求购/租赁/广告时才排除;拿不准必须保留。返回纯JSON数组。", "finePrompt":"你是闲鱼商品风险分析助手。根据商品详情判断是否值得用户人工查看。只做监测分析,不要鼓励自动联系卖家。优先识别:型号/规格不符、价格异常、疑似商家批量、维修/配件/求购、描述矛盾、成色/保修/拆修风险。拿不准可以通过,但理由必须提示待人工确认。返回JSON:{\"pass\": true/false, \"reason\": \"简短理由,包含关键风险或亮点\"}", "analysisMode":"hermes" }' ``` ## Hermes Report Generation After a task finishes, generate a local Markdown report from persisted candidates. Prefer the wrapper: ```bash node tools/xianyu_ops.mjs report --task --limit 30 ``` Or call the report script directly: ```bash cd /Users/chick/.Hermes/workspace/research/xianyu-hunter node tools/hermes_report.mjs --task --limit 30 # or omit --task to use the latest task node tools/hermes_report.mjs --limit 30 ``` The report is written to: ```text reports/-hermes-report.md ``` Use the generated report as a first-pass local risk summary, then add Hermes judgment in the chat response when BOSS asks for recommendations. ## Inspecting Results Use API while server is running: ```bash curl -sS http://127.0.0.1:3000/api/tasks | python3 -m json.tool curl -sS http://127.0.0.1:3000/api/tasks/ | python3 -m json.tool ``` Or inspect persisted tasks directly: ```bash cd /Users/chick/.Hermes/workspace/research/xianyu-hunter python3 - <<'PY' import json from pathlib import Path p=Path('data/tasks.json') if not p.exists(): print('no tasks.json') raise SystemExit for t in json.loads(p.read_text()): print('\n#', t.get('name'), t.get('id'), 'stage=', t.get('stage')) products=t.get('products',{}) print('raw/coarse/fine:', len(products.get('raw',[])), len(products.get('coarseFiltered',[])), len(products.get('fineFiltered',[]))) for item in products.get('fineFiltered',[])[:20]: print('-', item.get('title'), item.get('price') or item.get('detailPrice'), item.get('sellerLocation'), item.get('href')) if item.get('description'): print(' desc:', item['description'][:120].replace('\n',' ')) PY ``` When presenting results to BOSS, include: - Title and price. - Location/seller info. - Link. - Why it passed/fail if logs contain the reason. - Risk flags: price too low, “仅展示/配件/维修/求购”, no description, high 想要人数, seller looks commercial, missing proof/warranty. - Suggested next manual question if contacting seller is needed. ## Hermes Web Analysis + Notifications When BOSS asks to make xianyu-hunter more productized, prefer Web-visible features rather than backend-only endpoints. The current local fork can expose: - `POST /api/tasks/:id/analyze` to score fine-filtered candidates, persist `hermesAnalysis`, generate `reports/-analysis.md`, and optionally notify. - `GET/PUT /api/notify-config` backed by `data/notify-config.json` for Hermes webhook, Bark, PushPlus, and generic webhook channels. - A header **通知设置** modal, task-level **执行分析** button, and **Hermes 分析** tab with recommendation/caution/reject cards. Implementation and verification details are in `references/web-analysis-notifications-2026-05.md`. ## Scheduling with Hermes For scheduled monitoring, create a Hermes cron job whose prompt is self-contained and uses the CLI wrapper. A reusable prompt template is stored at: ```text /Users/chick/.Hermes/workspace/research/xianyu-hunter/tools/cron_prompt_template.md ``` Recommended cron job settings: - `workdir`: `/Users/chick/.Hermes/workspace/research/xianyu-hunter` - `enabled_toolsets`: `["terminal", "file"]` - `deliver`: origin/current chat - prompt: include task name, keywords, page count, region/price, requirements, and explicitly state no seller contact. The cron prompt should run: ```bash node tools/xianyu_ops.mjs run --name '<任务名>' --queries '<关键词1,关键词2>' --pages 1 --requirements '<需求>' --limit 30 ``` If login/captcha is required, the cron run should report that manual intervention is needed rather than trying to bypass verification. ## Web Login / Cookie Persistence The local BOSS fork should expose account login controls in the Web UI, not only through the CLI. The preferred product shape is a visible **账号登录 / Cookie** entry in the header that opens a login status panel. Expected implementation pattern: - `server.mjs` exposes login APIs: - `GET /api/login/status` — opens/uses the persistent Playwright profile to probe a real Goofish search page and reports `loggedIn`, `loginWall`, `cookieCount`, `cardCount`, current URL/title, and storage path. - `POST /api/login/open` — opens the persistent Chromium profile at Goofish for manual扫码/验证码 login. - `POST /api/login/wait` — waits/rechecks login completion using the same login detection as tasks. - `POST /api/login/close-browser` — closes the Playwright browser context without deleting cookies. - `public/index.html` header should have `账号登录 / Cookie`, opening a modal that explains the login flow and shows status. - `public/app.js` should render login status and logs instead of relying on alert-only UX. - Cookies are persisted automatically in the Playwright persistent profile at `browser-data/`; do not export or print raw cookies. - Cookie JSON upload should be treated as a fast local persistence step: after `ctx.addCookies()`, return status from `ctx.cookies()` only. Do **not** navigate to Goofish inside the import endpoint; run the slower real network/login probe only when the user clicks “检测登录状态”. Important detection pitfall: `nick--` and avatar elements can still exist on a login-wall page. Treat login as valid only when the search probe does **not** show `登录后可以更懂你` / `立即登录` / `请登录` and either product cards load or enough relevant cookies are present. Do not accept homepage-only login checks as sufficient. Session-specific implementation notes are captured in `references/web-login-cookie-panel-2026-05.md`. Cookie JSON import timeout and verification notes are captured in `references/cookie-json-import-timeout-2026-05.md`. Web dashboard QR-login returning a tiny 24x24 icon instead of the real QR, and the minimum-size selector fix, are captured in `references/qr-login-tiny-icon-fix-2026-05-07.md`. BOSS later simplified the preferred login UX: the visible Web login modal should expose only **获取/刷新登录二维码** and **刷新账号状态**; hide legacy buttons such as manual browser open, Cookie JSON upload, wait-detect, and close-session from the normal flow. Details are captured in `references/web-login-simplified-buttons-2026-05.md`. Login UX, persistent-profile lock recovery (`ProcessSingleton` / `SingletonLock`), and partial-result recovery from `coarseFiltered` are captured in `references/login-ux-locks-and-partial-results-2026-05.md`. Web task editing, manual save-only tasks, scheduling, `maxItems`, AI-optimize fallback, API smoke tests, and stale port restart pitfalls are captured in `references/web-task-editing-scheduling-ai-optimize-2026-05.md`. Existing task schedule updates through the running API, including the 6-hour monitor pattern and API/disk verification, are captured in `references/existing-task-schedule-api-2026-05.md`. Web AI optimize fallback and automatic Hermes analysis/notification are captured in `references/web-ai-fallback-and-auto-analysis-2026-05.md`. Web cache cleanup implementation notes are captured in `references/web-cache-cleanup-2026-05.md`. Web dashboard homepage/productized empty-state implementation notes are captured in `references/web-home-dashboard-polish-2026-05.md`. Home dashboard clickable overview/workflow cards and deep-link behavior are captured in `references/web-home-clickable-dashboard-cards-2026-05.md`. Portable skill/project packaging, safe archive exclusions, install script shape, and self-hosted Gitea publishing information requirements are captured in `references/portable-package-and-gitea-publishing-2026-05.md`. Gitea portable package sync workflow for updating the published package from the local messy working tree is captured in `references/gitea-portable-package-sync-2026-05.md`. Public Gitea publish verification, token-scrubbed remote handling, and final reporting checklist are captured in `references/gitea-public-publish-verification-2026-05.md`. Return navigation after deep-linking from the home dashboard is captured in `references/web-home-return-navigation-2026-05.md`. Item link normalization for mobile-clickable reports/notifications is captured in `references/item-link-normalization-2026-05.md`. Per-item notifications and Feishu Markdown clickable-link formatting are captured in `references/per-item-notifications-feishu-links-2026-05.md`. Single-run max notification item count (`maxNotifyItems`) is captured in `references/max-notify-items-config-2026-05.md`. Portable export packaging for sharing this skill/project with other Hermes instances is captured in `references/portable-skill-package-2026-05.md`. Important BOSS UX correction: do not present a direct `login.taobao.com` screenshot as the "Xianyu QR" even though Goofish uses Alibaba/Taobao unified login under the hood. Open/login from `goofish.com` first, label any redirect honestly, and prefer the visible browser login flow when BOSS wants to scan manually. Web QR source labeling + Hermes optimize handoff notes are captured in `references/web-qr-source-and-hermes-optimize-2026-05.md`. ## Troubleshooting ### Project asks for AI API configuration The local BOSS fork should not ask for API configuration. If this appears, verify you are running `/Users/chick/.Hermes/workspace/research/xianyu-hunter` and that `server.mjs` no longer gates `/api/tasks` behind `isConfigured()`. Also ensure the browser is loading `public/app.js?v=9` and `public/index.html` from the local fork. ### Browser asks for login or captcha This is expected. BOSS must complete it in the visible Chromium window. Do not attempt to bypass captcha. ### CLI login says OK but search page still shows login wall `node tools/xianyu_ops.mjs login` can produce a false-positive `loggedIn: true` if the homepage check is weak, while the search page body still contains `登录后可以更懂你` / `立即登录` and result cards never load. Verify with a real search page before blaming selectors: ```bash node --input-type=module <<'JS' import { chromium } from 'playwright'; const ctx = await chromium.launchPersistentContext('./browser-data', {headless:false}); const page = await ctx.newPage(); await page.goto('https://www.goofish.com/search?q='+encodeURIComponent('e3 1245 v3'), {waitUntil:'domcontentloaded', timeout:30000}); await page.waitForTimeout(8000); console.log((await page.locator('body').innerText()).slice(0,1000)); await ctx.close(); JS ``` If the body shows `登录后可以更懂你,推荐你喜欢的商品!立即登录`, ask BOSS to manually log in in the visible Chromium window, then rerun the task. Do not treat zero results as a valid market result in this state. ### Search returns zero or selector errors Goofish DOM changes often. Re-check selectors in: - `lib/search.mjs` card selector: `a[class*="feeds-item-wrap"]` - title selector: `[class*="row1-wrap-title"]` - price selector: `[class*="price-wrap"]` - detail selector in `lib/filter.mjs` Open the browser page and inspect manually if needed. ### Task enters chat stage unexpectedly The local BOSS fork should no longer enter `chatting`; `lib/task.mjs` stops after detail collection and clears `chatSessions`. If a task enters chat, you are probably running upstream code or an old cached working tree. Stop the task and re-check `lib/task.mjs` for `ChatManager` imports. ### Port conflict Use another port: ```bash PORT=3010 npm start ``` Set helper base URL: ```bash XIANHU_BASE_URL=http://127.0.0.1:3010 node tools/create_monitor_task.mjs ... ``` ## Recommended Future Hardening If BOSS wants this as a durable production monitor, implement these patches in the repo: 1. Add `chatEnabled: false` task config and skip Stage 5 unless enabled. 2. Add a read-only CLI/API endpoint that returns candidate listings + AI reasons without starting chats. 3. Add scheduled runs with deduplication and notifications back to Hermes/Feishu. 4. Store task templates separately from results. 5. Add rate limits and cooldowns per keyword/account. 6. Add export formats: Markdown report, CSV, JSON. ## Verification Checklist - [ ] `node -v` is >= 18. - [ ] `npm install` completed in the repo clone. - [ ] `npx playwright install chromium` completed. - [ ] `node tools/xianyu_ops.mjs start --port 3000` launches the local service. - [ ] `node tools/xianyu_ops.mjs status --port 3000` reports service state. - [ ] Browser is logged into goofish.com. - [ ] Task uses modest page count and monitoring-focused requirements. - [ ] No AI/API settings banner appears in the dashboard. - [ ] Task stops after detail collection; no seller contact/chat stage runs. - [ ] `node tools/hermes_report.mjs --limit 30` can generate a report from `data/tasks.json`. - [ ] Results are summarized with links, prices, risk flags, and suggested manual next steps.