Files
xianyu-hunter-hermes-skill/skill/xianyu-hunter-monitor/references/login-ux-locks-and-partial-results-2026-05.md
T

3.7 KiB

Goofish Login UX, Browser Lock, and Partial-Result Recovery — 2026-05

What happened

During a Goofish/Xianyu search task, a temporary helper opened a direct Taobao unified-login URL and sent its screenshot as a "real login QR". BOSS correctly objected that it looked like a Taobao login page and not the expected Xianyu entry.

Goofish web login is backed by Alibaba/Taobao account infrastructure, so login.taobao.com can be normal after following the Goofish login flow. However, for BOSS UX, do not present a direct Taobao URL/screenshot as if it were the Xianyu login entry.

Preferred login workflow

  1. Start/keep the dashboard service.
  2. Open https://www.goofish.com/ in the persistent Playwright profile (browser-data/).
  3. Let BOSS interact with the visible browser window and click the Goofish page's own login/modal/QR controls.
  4. If a screenshot is needed, label it accurately: "Goofish page login/modal; may redirect to Taobao unified login".
  5. After BOSS says login is done, close any temporary helper Chromium using the same profile before running task automation.
  6. Verify with GET /api/login/status against a real search page, not homepage only.

Pitfall: ProcessSingleton / SingletonLock

If a temp QR/login helper is still using browser-data/, later dashboard/API/task runs may fail with:

browserType.launchPersistentContext: Failed to create a ProcessSingleton for your profile directory
... browser-data/SingletonLock: File exists (17)

Safe recovery used in this session:

cd /Users/chick/.Hermes/workspace/research/xianyu-hunter
pkill -f 'xianyu_goofish_login_entry_tmp.mjs|xianyu_qr_login_tmp.mjs' || true
pkill -f 'Google Chrome for Testing.*xianyu-hunter/browser-data' || true
sleep 2
for p in $(lsof -tiTCP:3000 -sTCP:LISTEN 2>/dev/null); do kill "$p" 2>/dev/null || true; done
sleep 1
PORT=3000 node server.mjs

Then verify:

curl -sS -m 60 http://127.0.0.1:3000/api/login/status | python3 -m json.tool

A good result includes loggedIn: true, loginWall: false, nonzero cookieCount, and product cards on a search URL.

Partial-result recovery

If a run is interrupted during fine_filter, tools/hermes_report.mjs may report 候选 0 because it only sees fineFiltered. Do not conclude there were no products. Inspect data/tasks.json and mine products.coarseFiltered or products.raw directly.

Example used for E3-1245v3:

python3 - <<'PY'
import json,re
from pathlib import Path
p=Path('data/tasks.json')
data=json.loads(p.read_text())
t=[x for x in data if x.get('id')=='<task_id>'][0]
items=t.get('products',{}).get('coarseFiltered',[]) or t.get('products',{}).get('raw',[])
def price_num(v):
    m=re.search(r'(\d+(?:\.\d+)?)', str(v or '').replace(',',''))
    return float(m.group(1)) if m else None
for it in items:
    title=(it.get('title') or '').lower().replace('-',' ')
    text=' '.join(str(it.get(k,'')) for k in ['title','description','detailDescription']).lower()
    if '1245' in title and 'v3' in title and not any(w in text for w in ['回收','求购','主板','套装','整机','散热','维修','不包含 cpu']):
        print(it.get('price') or it.get('detailPrice'), it.get('location') or it.get('sellerLocation'), it.get('title'), it.get('href') or it.get('url'))
PY

Presentation guidance

When reporting results to BOSS:

  • State the live status first (login ok, task id, counts raw/coarse/fine, whether run completed or was interrupted).
  • If a report says 0 candidates but raw/coarse has data, explicitly explain that this is a stage/report limitation.
  • Rank candidates by closeness to budget and risk, and call out exclusions (e.g. "不包含 CPU", "不能进系统", "回收", "主板套装").