Files
chick efd6eb8fb9 Fix xianyu QR login refresh
Exclude tiny QR-login icon candidates, expose captured QR dimensions in the Web UI, and refresh the portable Hermes skill release archives.
2026-05-07 15:29:05 +08:00

454 lines
22 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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`: 13 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 <task_id> --limit 30
```
Or call the report script directly:
```bash
cd /Users/chick/.Hermes/workspace/research/xianyu-hunter
node tools/hermes_report.mjs --task <task_id> --limit 30
# or omit --task to use the latest task
node tools/hermes_report.mjs --limit 30
```
The report is written to:
```text
reports/<task_id>-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/<task_id> | 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/<task_id>-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.